super
在py3的用法python
class A(object): def func(self): print("A") class B(A): def func(self): super().func() print("B") class C(A): def func(self): super().func() print("C") class D(B, C): def func(self): super(D, self).func() print("D") D().func() class User: def __init__(self, name): self.name = name class VIPUser(User): def __init__(self, name, level, start_date, end_date): super().__init__(name) self.level = level self.start_date = start_date self.end_date = end_date 太白 = VIPUser('太白', 6, '2019-01-01', '2020-01-01') print(太白.__dict__)
在py2中(新式类/经典类)中的用法安全
封装微信
广义上的封装 : 把属性和方法装起来,外面不能直接调用了,要经过类的名字来调用app
狭义上的封装 : 把属性和方法藏起来,外面不能调用,只能在内部偷偷调用函数
使用私有属性和方法的三种状况微信支付
没法看和改code
class User: # def __init__(self, name, passwd): # self.usr = name # self.__pwd = passwd # # alex = User('alex', 'alexsb') # # print(alex.__pwd) # # AttributeError: 'User' object has no attribute '__pwd' # print(alex.pwd) # # AttributeError: 'User' object has no attribute '__pwd' # 给一个名字前面加上了双下划綫的时候,这个名字就变成了一个私有的 # 全部的私有的内容或者名字都不能在累的外部调用,只能在类的内部使用了
可看不可改对象
class User: def __init__(self, name, passwd): self.user = name self.__pwd = passwd def get_cwd(self): return self.__pwd alex = User('alex', 'alexsb') print(alex.get_cwd()) # alexsb # 私有 + 某个get方法实现的
可看可改(须要按照规则来改),ip
class User: # def __init__(self, name, passwd): # self.user = name # self.__pwd = passwd # # def get_cwd(self): # return self.__pwd # # def set_pwd(self): # pass # set_pwd表示用户 必须调用咱们自定义的吸怪方式来进行变量的修改 私有 + changge方法实现
封装的语法md5
私有的静态变量
class User: __Country = 'china' def func(self): print(User.__Country) # print(User.__Country) # 类的外部不能调用 # AttributeError: type object 'User' has no attribute '__Country' User().func() # china
私有的实例变量
import hashlib class User: def __init__(self, name, passwd): self.user = name self.__pwd = passwd def __get_md5(self): md5 = hashlib.md5(self.__pwd.encode("utf-8")) return md5.hexdigest() def getpwd(self): return self.__get_md5() alex = User('alex', 'alexsb') print(alex.getpwd())
私有的绑定方法
import hashlib class User: def __init__(self, name, passwd): self.user = name self.__pwd = passwd def __get_md5(self): md5 = hashlib.md5(self.__pwd.encode("utf-8")) return md5.hexdigest() def getpwd(self): return self.__get_md5() alex = User('alex', 'alexsb') print(alex.getpwd()) # 全部的私有化都为了让用户不在外部调用类中的某个名字 # 若是彻底私有化,name这个类的封装读更高了 # 封装度越高 各类属性和方法的安全性也越高,可是代码越复杂
私有的特色
在类的内部使用
内部能够正常调用
类的外部使用
没法再外部使用
类的子类中使用
没法再子类中使用
# class Foo(object): # def __init__(self): # self.func() # # def func(self): # print("in Foo") # # # class Son(Foo): # def func(self): # print("IN SON") # Son() # IN SON # class Foo(object): # def __init__(self): # self.__func() # # def __func(self): # print("in Foo") # # # class Son(Foo): # def __func(self): # print("in son") # # Son() # in Foo class Foo(object): def __func(self): print("in Foo") class Son(Foo): def __init__(self): self.__func() Son() # AttributeError: 'Son' object has no attribute '_Son__func'
原理
加了双下划线的名字为啥没法从类的外部调用
class User: __Country = 'China' __Role = '法师' def func(self): print(self.__Country) # 在类的内部使用的时候,自动的把当前这句话所在的类的名字拼接在私有变量前完成变形 print(User._User__Country) print(User._User__Role) # China # 法师 # __Country -->'_User__Country': 'China' # __Role -->'_User__Role': '法师' # User.__aaa = 'bbb' # 在类的外部根本不能定义私有的概念
类中变量的级别,那些是python支持的,那些是python不支持的
# public 公有的 类内类外都能用,父类子类都能用 python支持 # protect 保护的 类内能用,父类子类都能用,类外不能用 python不支持 # private 私有的 本类的类内部能用,其余地方都不能用 python支持
类最终的三个装饰器(内置函数)
property
做用 : 把一个方法假装成一个属性,在调用这个方法的时候不须要加()就能够直接获得返回值
from math import pi class Circle: def __init__(self, r): self.r = r @property def area(self): return pi * self.r ** 2 c1 = Circle(5) print(c1.r) print(c1.area) # 5 # 78.53981633974483
import time class Person: def __init__(self, name, birth): self.name = name self.birth = birth @property def age(self): return time.localtime().tm_year - self.birth 太白 = Person('太白', 1998) print(太白.age)
property的第二个应用场景 : 和私有的属性合做的
class User: def __init__(self, user, pwd): self.user = user self.__pwd = pwd @property def pwd(self): return self.__pwd alex = User('alex', 'alexsb') print(alex.pwd) class Goods: # discount = 0.8 # def __init__(self, name, origin_price): # self.name = name # self.__price = origin_price # # @property # def price(self): # return self.__price * self.discount # # apple = Goods('apple', 5) # print(apple.price) # # 4.0
setter
class Goods: # discount = 0.8 # def __init__(self, name, origin_pricce): # self.name = name # self.__price = origin_pricce # # @property # def price(self): # return self.__price * self.discount # # @price.setter # def price(self, new_value): # if isinstance(new_value, int): # self.__price = new_value # # apple = Goods('apple', 5) # print(apple.price) # apple.price = 10 # print(apple.price) # 4.0 # 8.0
delter
class Goods: # discount = 0.8 # def __init__(self, name, origin_price): # self.name = name # self.__price = origin_price # # @property # def price(self): # return self.__price * self.discount # # @price.setter # def price(self, new_value): # if isinstance(new_value, int): # self.__price = new_value # # @price.deleter # def price(self): # del self.__price # # apple = Goods('apple', 5) # print(apple.price) # apple.price = 'asd' # del apple.price # 调用对应的被@price.deleter装饰的方法 # print(apple.price)
classmethod
staticmethod
反射
用字符串数据类型的名字来操做这个名字对应的函数\实例变量\绑定方法\各类方法
.反射对象的 实例变量
class Person: def __init__(self, name, age): self.name = name self.age = age def qqxing(self): print("qqxing") alex = Person('alex', 83) wusir = Person('wusir', 74) ret = getattr(alex, 'name') print(ret) ret = getattr(wusir, 'name') print(ret) ret = getattr(wusir, 'qqxing') ret() # alex # wusir # qqxing
反射类的 静态变量/绑定方法/其余方法
class A: # Role = '治疗' # # def __init__(self): # self.name = 'alex' # self.age = 84 # # def func(self): # print("wahaha") # return 666 # # a = A() # print(getattr(a, 'name')) # print(getattr(a, 'func')()) # print(getattr(A, 'Role')) # # alex # # wahaha # # 666 # # 治疗
模块中的 全部变量
被导入的模块
import a print(a.Wechat) print(a.Alipay) # <class 'a.Wechat'> # <class 'a.Alipay'> # # 对象名.属性名 ==> getattr(对象名,'属性名') # # a.Alipay ==> getattr(a,'Alipay') print(getattr(a, 'Alipay')) print(getattr(a, 'Wechat')) # <class 'a.Alipay'> # <class 'a.Wechat'>
当前执行的py文件 - 脚本
import a import sys # print(sys.modules) # print(sys.modules['a'].Alipay) # print(a.Alipay) # <class 'a.Alipay'> # <class 'a.Alipay'> print(getattr(a, 'Alipay')) print(getattr(sys.modules['a'], 'Alipay')) # <class 'a.Alipay'> # <class 'a.Alipay'> wahaha = 'hahaha' print(getattr(sys.modules['__main__'], 'wahaha')) # hahaha
反射实现归一化思想
class Payment:pass class Alipay(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'uname':self.name,'price':money} print('%s经过支付宝支付%s钱成功'%(self.name,money)) class WeChat(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'username':self.name,'money':money} print('%s经过微信支付%s钱成功'%(self.name,money)) class Apple(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'name': self.name, 'number': money} print('%s经过苹果支付%s钱成功' % (self.name, money)) class QQpay: def __init__(self,name): self.name = name def pay(self,money): print('%s经过qq支付%s钱成功' % (self.name, money)) import sys def pay(name,price,kind): class_name = getattr(sys.modules['__main__'],kind) obj = class_name(name) obj.pay(price) # if kind == 'Wechat': # obj = WeChat(name) # elif kind == 'Alipay': # obj = Alipay(name) # elif kind == 'Apple': # obj = Apple(name) # obj.pay(price) pay('alex',400,'WeChat') pay('alex',400,'Alipay') pay('alex',400,'Apple') pay('alex',400,'QQpay')
反射一个函数
class A: Role = '治疗' def __init__(self): self.name = 'alex' self.age = 84 def func(self): print('wahaha') return 666 a = A() if hasattr(a, 'func'): if callable(getattr(a, 'func')): getattr(a, 'func')() # wahaha