类的封装
-
super
在py3的用法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中(新式类/经典类)中的用法
- super是按照mro顺序来寻找当前类的下一个类
- 在py3中不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法
- 在py2中的新式类中,需要我们主动传递参数super(子类的名字,子类的对象).函数名()、
- 在py2的经典类中,并不支持使用super来找下一个类
- 在D类中找super的func,那么可以这样写 super().func()
- 也可以这样写 super(D,self).func() (并且在py2的新式类中必须这样写)
-
封装
-
广义上的封装 : 把属性和方法装起来,外面不能直接调用了,要通过类的名字来调用
-
狭义上的封装 : 把属性和方法藏起来,外面不能调用,只能在内部偷偷调用
-
使用私有属性和方法的三种情况
-
无法看和改
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方法实现的
-
可看可改(需要按照规则来改),
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方法实现
-
-
封装的语法
-
私有的静态变量
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
-