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