簡(jiǎn)單例子1
內(nèi)建函數(shù)setattr() getattr() hasattr() 即使類中沒有setattr 和 getattr魔術(shù)方法也不會(huì)報(bào)錯(cuò) 不同于len(A()), 如果類中沒有len方法則會(huì)報(bào)錯(cuò) setattr時(shí)倘感,第2個(gè)位置的參數(shù),可以是屬性,也可以是方法,例如增加x屬性,也可以是方法x。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n1457" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"> class Point:
def init(self, x, y):
self.x = x
self.y = y
def str(self):
return "Point({}, {})".format(self.x, self.y)
def show(self):
print(self)
p = Point(1, 2)
動(dòng)態(tài)增加或修改
print('*******')
print(setattr(p, 'x', 99)) # None
print(setattr(p, 'z', 100)) # None
print(p.dict)
獲取
print(getattr(p, 'y')) # 2
print(getattr(p, 'q', None)) # None
print(getattr(p, 'dict'))
{'x': 99, 'y': 2, 'z': 100},屬性獲取
print(p.dict)
{'x': 99, 'y': 2, 'z': 100}, 實(shí)例字典獲取
判斷
print(hasattr(p, 'a')) # False
print(hasattr(p, 'x')) # True</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1459" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"> # 綜合例子
通過實(shí)例判斷恐疲,獲取屬性
if hasattr(p, 'show'):
getattr(p, 'show')() # Point(99, 2)
getattr返回一個(gè)綁定方法show,調(diào)用show方法。
通過 實(shí)例 判斷套么,動(dòng)態(tài)增加屬性(用的少)
if not hasattr(p, 'sub'):
setattr(p, 'sub', lambda point1, point2: Point(point1.x - point2.x, point1.y - point2.y))
print(p.sub(Point(1, 2, ), Point(3, 3))) # Point(-2, -1)
通過 類 判斷培己,動(dòng)態(tài)增加類屬性
if not hasattr(Point, 'add'):
setattr(Point, 'add', lambda point1, point2: Point(point1.x + point2.x, point1.y + point2.y))
print(p.dict) # 實(shí)例字典中有sub方法
print(Point.dict) # 類字典中有add方法,沒有sub方法</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1461" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"> # 只用來測(cè)試(不優(yōu)雅)
class Point:
def init(self, x, y):
self.x = x
self.y = y
def str(self):
return "Point({}, {})".format(self.x, self.y)
def show(self):
print(self.x, self.y)
def len(self):
return 10
p = Point(1, 2)
感覺這兩個(gè)差不多
print(Point.dict) # 類字典胚泌。魔術(shù)方法省咨,存在類字典中
print(dir(Point)) # 父類和實(shí)例的各種方法及屬性,包括魔術(shù)方法玷室,不包括x, y, z 零蓉,有序列表
print(p.dict) # 只有x,y笤受,實(shí)例字典只存放init中的內(nèi)容
print(dir(p)) # 最全,父類和實(shí)例的各種方法及屬性敌蜂,包括魔術(shù)方法箩兽,包括x, y, z, 有序列表
print(p.dir()) # 同dir(p), 無序列表
print(Point.dir(p)) # 同dir(p), 無序列表。類調(diào)用方法(魔術(shù)和普通)章喉,都不會(huì)注入第一參數(shù)
p.dict['x'] = 99 # 相當(dāng)于調(diào)用setattr方法
print(p.dict)
p.z = 100 # 相當(dāng)于調(diào)用setattr方法
print(p.dict) # 增加一個(gè)z
print(p.z) # 相當(dāng)于調(diào)用getattr方法
</pre>
-
魔術(shù)方法setattr getattr delattr getattribute
setattr
-
調(diào)用setattr 的情景
init 函數(shù)中汗贫,self.x = x
在類的外面 obj.x = 50
在類的外面 setattr(obj, 'x', 50)
不會(huì)調(diào)用setattr 的情景
obj.dict['x'] = 50
setattr 魔術(shù)方法
-
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1479" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 這個(gè)方法可以攔截對(duì)實(shí)例屬性的增加,修改操作囊陡,如果設(shè)置生效,實(shí)例的字典為空 # 實(shí)例通過.點(diǎn)號(hào)設(shè)置屬性敷存,例如設(shè)置self.x = x屬性悔详,就會(huì)調(diào)用
class Point:
z = 6
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
def setattr(self, key, value):
self.dict.setitem(key, value)
等價(jià)于 self.dict[key] = value
p = Point(1, 2)
p.x = 20
print(p.dict) # {'x': 20, 'y': 2}因?yàn)槌跏蓟瘯r(shí)也會(huì)調(diào)用2次
setattr
setattr , 但是如果實(shí)例的屬性要加到實(shí)例的dict中, 需要自己手動(dòng)完成, 如果不手動(dòng)添加,則默認(rèn)dict是清空的 </pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1481" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">
如果只增加setattr方法租冠,則實(shí)例字典會(huì)被清空
可以通過實(shí)例字典設(shè)置屬性搪花,但是取不出來屬性遏片,即無法使用obj.x
class Point:
z = 6
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
def setattr(self, key, value):
print("setattr {} = {}".format(key, value))
p = Point(1, 2)
print(Point.dict) # 有值
print(p.dict) # 如果只增加setattr方法,實(shí)例字典被空的
因?yàn)閷?shí)例字典被清空了撮竿,而且也不會(huì)調(diào)用內(nèi)鍵函數(shù)getattr(),所以報(bào)錯(cuò)
print(p.x) # 報(bào)錯(cuò)
print(p.y) # 報(bào)錯(cuò)
print(p.z) # 6
p.x = 50 # 還會(huì)調(diào)用setattr
print(p.x) # 剛設(shè)置完x屬性吮便,但還是取不到x屬性,因?yàn)閷?shí)例字典還是空的
print(p.dict) # {}
p.dict['x'] = 60 # 只有在實(shí)例的字典中添加x屬性幢踏,才可以取到x屬性髓需,但是不會(huì)調(diào)用setattr
print(p.dict) # 字典中有值{'x': 60}
print(p.x) # 60</pre>
getattr
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1484" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 如果只增加getattr方法和原來沒有什么變化,相當(dāng)于沒增加房蝉,一般不這么用
class Point:
z = 6
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
def getattr(self, item):
return "missing {}".format(item)
p = Point(1, 2)
print(Point.dict) # 有值
print(p.dict) # 如果只實(shí)現(xiàn)了getattr方法僚匆,實(shí)例字典中有值{'x': 1, 'y': 2}
print(p.x) # 1
print(p.y) # 2
print(p.z) # 6
p.m = 50 # 因?yàn)闆]有實(shí)現(xiàn)setattr方法,所以調(diào)用的是內(nèi)鍵函數(shù)setattr()
print(p.m) # 50
print(p.dict) # 實(shí)例字典中有值{'x': 1, 'y': 2, 'm': 50}
p.dict['x'] = 60 # 只有在實(shí)例的字典中添加x屬性搭幻,才可以取到x屬性咧擂,但是不會(huì)調(diào)用setattr
print(p.dict) # 實(shí)例字典中有值x被改成{'x': 60, 'y': 2}
print(p.x) # 60
</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1487" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># getattr 魔術(shù)方法
查找屬性順序
instance.dict -> instance.class -> 繼承類 —> object字典
class Base(object):
n = 0
z = 200
class Point(Base):
z = 6
x = 100
def init(self, x, y):
self.x = x
self.y = y
def getattr(self, item):
return "missing {}".format(item)
p = Point(1, 2)
print(Point.dict)
print(p.dict)
雖然父類沒有實(shí)現(xiàn)setattr
但是object中實(shí)現(xiàn)了setattr
print(p.x) # 1
print(p.y) # 2
print(p.z) # 6
print(p.n) # 0
print(p.t) # missing 找了一圈找不到就會(huì)調(diào)用 getattr方法,
</pre>
setattr getattr綜合應(yīng)用的例
-
大多數(shù)情況都是這兩種魔術(shù)方法同時(shí)使用
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1494" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 其實(shí)不用實(shí)現(xiàn)這兩個(gè)魔術(shù)方法檀蹋,就可以滿足開發(fā)需求
lass Point:def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
p = Point(1, 2)
print(p.x) # 1
print(p.y) # 2
p.z = 9
print(p.z) # 9
</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1496" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 如果想使用__setattr__ 和 __getattr__松申,則正常使用的例子
class Point:
z = 6
def __init__(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用__setattr__
self.y = y
def __getattr__(self, item):
return item
def __setattr__(self, key, value):
# 直接操作字典不會(huì)遞歸
self.__dict__[key] = value
p = Point(1, 2)
print(Point.__dict__) # 有值
print(p.__dict__) # 有值
print(p.x) # 1
print(p.y) # 2
print(p.z) # 6
p.x = 50 # 還會(huì)調(diào)用因?yàn)閷?shí)現(xiàn)了__setattr__,所以會(huì)調(diào)用__setattr__俯逾,內(nèi)部打印字符串就可以看到
print(p.x) # 50
print(p.__dict__) # 有值
p.__dict__['x'] = 60 # 實(shí)例的字典中添加x屬性贸桶,但是不會(huì)調(diào)用__setattr__,內(nèi)部打印字符串就可以看到
print(p.__dict__) # 有值
print(p.x) # 60</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1499" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 內(nèi)鍵函數(shù)與魔術(shù)方法的區(qū)別例子
setattr()函數(shù)桌肴,當(dāng)類中實(shí)現(xiàn)了setattr方法時(shí)皇筛,會(huì)走類中的這個(gè)方法
getattr()函數(shù),當(dāng)類中實(shí)現(xiàn)了getattr方法時(shí)识脆,并且實(shí)例的字典中沒有要獲取的屬性時(shí)设联,才會(huì)走類中的這個(gè)方法
class Point:
z = 6
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
def getattr(self, item):
print('111111')
return 'item: {}'.format(item)
def setattr(self, key, value):
直接操作字典不會(huì)遞歸
print('222222')
self.dict[key] = value
p = Point(1, 2)
p.x = 50 # 調(diào)用setattr
print(p.x) # 實(shí)例的字典中取到了50善已,沒調(diào)用getattr
print(p.m) # 實(shí)例的字典中沒有m屬性,才會(huì)調(diào)用getattr
setattr(p, 'n', 99) # 調(diào)用setattr
print(p.n) # 取實(shí)例的字典中n屬性离例,沒調(diào)用getattr
print(p.m) # 實(shí)例的字典中沒有m屬性换团,才會(huì)調(diào)用getattr
print(getattr(p, 'n')) # 從字典中取
print(getattr(p, 't')) # 調(diào)用getattr</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1501" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 測(cè)試用例,正常代碼不這么寫
class Point:
z = 6
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
self.y = y
def getattr(self, item):
return "missing {}".format(item)
def setattr(self, key, value):
print("setattr {} = {}".format(key, value))
p = Point(1, 2)
print(Point.dict) # 有值
print(p.dict) # 空的
因?yàn)閷?shí)例字典被清空了宫蛆,但是類字典沒有被清空艘包,所以取不到x,y,但是能取到z
print(p.x) # missing x
print(p.y) # missing t
print(p.z) # 6
p.x = 50 # 還會(huì)調(diào)用setattr
print(p.x) # 剛設(shè)置完x屬性,但還是取不到x屬性耀盗,因?yàn)閷?shí)例字典還是空的
print(p.dict) # {}
p.dict['x'] = 60 # 只有在實(shí)例的字典中添加x屬性想虎,才可以取到x屬性,但是不會(huì)調(diào)用setattr
print(p.dict) # 字典中有值{'x': 60}
print(p.x) # 60
</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1503" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">class Base:
n = 0 class Point(Base):
z = 6
d = {}
def init(self, x, y):
self.x = x # 這時(shí)會(huì)調(diào)用setattr
setattr(self, 'y', y)
self.dict['a'] = 5
def getattr(self, item):
print("missing {}".format(item))
return self.d[item]
def setattr(self, key, value):
print("setattr {} = {}".format(key, value))
self.d[key] = value
p = Point(1, 2)
print('+++++++++++++')
print(Point.dict)
print(p.dict)
print(p.x) # missing x 當(dāng)找到類的字典時(shí)叛拷,'d'下面有'x', 但是外面沒有'x', d': {'x': 1, 'y': 2}
print(p.z) # 6
print(p.n) # 0
print(p.t) # missing t
print(p.a) # 5 </pre>
delattr( 了解)
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1506" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">class Point:
z = 6
def init(self, x, y):
self.x = x
self.y = y
def delattr(self, item):
return print('Can not del {}'.format(item))
p = Point(1, 2)
del p.x
p.z = 15
del p.z
不能刪除了</pre>
getattribute(了解)
實(shí)例的所有屬性訪問舌厨,第一個(gè)都會(huì)調(diào)用這個(gè)方法,它阻止了屬性的查找順序忿薇,
該方法應(yīng)該返回計(jì)算后的值裙椭,或者拋出一個(gè)Attribute Error異常
它的return值將作為屬性查找的結(jié)果
如果拋出AttributeError, 則會(huì)直接調(diào)用 getattr方法署浩,因?yàn)閷傩詻]有找到
屬性查找順序
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1517" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># instance.getattribute ->instance.dict -> instance.class -> 祖類 —> object字典</pre>
使用方法
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1519" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># getattribute方法中為了避免出現(xiàn)無限遞歸揉燃,它的實(shí)現(xiàn)應(yīng)該永遠(yuǎn)調(diào)用基類的同名方法以訪問需要的任何屬性,例如:object.getattribute(self, name),
一般不要使用這個(gè)方法</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1520" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">class Point(Base):
z = 6
def init(self, x, y):
self.x = x
self.y = y
def getattr(self, item):
return("missing {}".format(item))
def getattribute(self, item):
return object.__getattribute(self, item)
return super().getattribute(item)
p = Point(1, 2)
print('+++++++++++++')
print(Point.dict)
print(p.dict)
print(p.x) # 1
print(p.z) # 6
print(p.n) # 0
print(p.t) # missing t </pre>
增加子類功能的3種方法
1筋栋、直接繼承然后修改炊汤,2、給子類增加一個(gè)裝飾器弊攘, 3抢腐、Mixin Mixin就是其他類混合進(jìn)來,同時(shí)帶來了類的屬性和方法肴颊,本質(zhì)上是多繼承氓栈,是一種組合的設(shè)計(jì)模式。和裝飾器比較婿着,兩者的裝飾效果一樣授瘦,但是Mixin是類,可以繼承竟宋。 Mixin類的使用原則:
Mixin類中不應(yīng)該顯示的出現(xiàn)init方法
Mixin類通常不能獨(dú)立工作提完,因?yàn)樗菧?zhǔn)備混入別的類中,實(shí)現(xiàn)部分功能
-
Mixin類的祖先類也應(yīng)該是Mixin類
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1531" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 直接繼承
class Document: #因?yàn)橛衟rint方法未實(shí)現(xiàn)丘侠,所以稱為抽象基類
def init(self, content):
self.content = contentdef print(self):
raise NotImplementedError
class Word(Document):
def print(self):
print(self.content, 'word style')
class Pdf(Document):
def print(self):
print(self.content, 'pdf style')
class Test(Document): #在python中徒欣,這個(gè)子類可以不實(shí)現(xiàn)父類中的print方法,
# 但是在其他語言中蜗字,如果繼承自父類打肝,但是父類的抽象方法脂新,未能全部實(shí)現(xiàn),
# 則這個(gè)子類也屬于抽象類粗梭,抽象類不可以實(shí)例化
pass
w = Word('tutu')
w.print()
#裝飾器
class Document:
def __init__(self, content):
self.content = content
class Word(Document):
pass
# 裝飾器1
def printable(cls):
def wrapper(content):
cls.print = lambda: print(content)
return cls
return wrapper
# 裝飾器2
def printable(cls):
def wrapper(content):
def fn():
print(content)
cls.print = fn
return cls
return wrapper
# 裝飾器3 **********************************
def printable(cls):
def fn(self): # 這3行等價(jià)于 cls.print = lambda self: print(self.content)
print(self.content)
cls.print = fn
return cls
# 裝飾器4争便,注意使用print時(shí),不要出現(xiàn)遞歸
def printable(cls):
def _print(self): # 寫在類的外面的断医,但是需要給類添加的方法滞乙,第一個(gè)參數(shù)必須為self
print(self.content)
cls.print = _print
return cls
@printable #PrintableWord = printable(PrintableWord)
class PrintableWord(Word):pass
p = PrintableWord('abs')
p.print()
# Mixin,多繼承
# PrintableMixin一般值需要里面的print方法鉴嗤,里面一般不寫__init__
class Document:
def __init__(self, content):
self.content = content
class Word(Document):
pass
class PrintableMixin:
def print(self): #這個(gè)兩個(gè)print不會(huì)出現(xiàn)遞歸斩启,因?yàn)榈谝粋€(gè)print相當(dāng)于有一個(gè)隱藏的名字,
# 只能通過這兩種方法調(diào)用醉锅,PrintableMixin.print(instance) p.print()
print(self.content)
class PrintableWord(PrintableMixin, Word):pass
p = PrintableWord('abs')
p.print()
#print(PrintableMixin.__dict__)
# Mixin增強(qiáng)
class Document:
def __init__(self, content):
self.content = content
class Word(Document):
pass
# Mixin功能兔簇,多繼承
class PrintableMixin:
def print(self):
print(self.content)
class SuperPrintableMixin(PrintableMixin):
def print(self):
print('增強(qiáng)之前打印:', self.content)
super().print()
print('增強(qiáng)之后打印:')
class PrintableWord(SuperPrintableMixin, Word): pass
p = PrintableWord('abs')
p.print()
</pre>
python2.7與python本質(zhì)區(qū)別(了解)
python2.7中與python3的不同: 都不同python3 type(A), dir(A) a.class
dir() 函數(shù)的用法 dir(A) 收集對(duì)象的屬性
模塊化
模塊化是組織代碼的方式,封裝代碼荣挨,封裝就是邊界
在其他編程語言中男韧,庫朴摊、包默垄、模塊是同一種概念,是代碼組織方式
在python中:
模塊module:python文件
包package:是指模塊組織在一起的甚纲,和包同名目錄及其相關(guān)文件
導(dǎo)入語法
-
import 只能加模塊名
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1552" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 完全限定名稱訪問path
import os.path # 導(dǎo)入os.path, os加入當(dāng)前名字空間
print(dir()) # 里面只有os,沒有os.path</pre> -
import as
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1555" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">import os.path as osp # 導(dǎo)入os.path并賦值給osp
print(dir()) # 里面只有osp</pre> -
局部導(dǎo)入
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1558" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">def testimport():
import os.path
print(dir()) # os存在里面
testimport()
print(globals().keys()) # os不存在里面
</pre> -
總結(jié)
導(dǎo)入頂級(jí)模塊口锭,其名稱會(huì)加入到本地名詞空間中,并綁定到其模塊對(duì)象
導(dǎo)入非頂級(jí)模塊介杆,只將其頂級(jí)模塊名稱導(dǎo)入到本地名詞空間鹃操。導(dǎo)入的模塊必須使用完全限定名稱來訪問。
如果使用了as, as后的名稱直接綁定到導(dǎo)入的模塊對(duì)象春哨,并將該名稱加入到本地名詞空間
-
其他例子:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1570" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">from functools import wraps as wr, partial
print(dir()) # [..., 'wr', 'partial']</pre>四種方式獲得同一個(gè)對(duì)象的 exists
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1572" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">import os
print(os.path.exists)
print(exists)
print(os.path.dict['exists']) # 字符串,os.path被導(dǎo)入之后荆隘,可以取dict
print(getattr(os.path, 'exists')) # 字符串, module對(duì)象也可以使用getattr來獲得屬性</pre> -
from 必須加模塊 import 類名,函數(shù)名赴背,模塊名
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1575" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">from pathlib import Path # 導(dǎo)入類Path
print(Path, id(Path))
import pathlib as p1
print(p1.Path, id(p1.Path)) # p1.Path 與 Path 是同一個(gè)對(duì)象,id相同</pre>
自定義模塊
模塊名:由字母數(shù)字下劃線組成椰拒,不能以數(shù)字開頭,不能有中文
不要使用系統(tǒng)模塊名凰荚,以避免沖突燃观,通常模塊名為全小寫,下劃線來分割便瑟。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1579" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># test1.py
class A:
def showmodule(self):
print(1, self.module, self)
print(2, self.dict)
print(3, self.class.dict)
print(4, self.class.name)
a = A()
a.showmodule() # self.module = 'main'
test2.py
import test1
a = test1.A()
a.showmodule() # self.module = 'test1'
test3.py
from test1 import A as cls
a = cls()
a.showmodule() # # self.module = 'test1'</pre>
模塊搜索順序
會(huì)從sys.path中缆毁,從前到后依此查找,并不搜索這些目錄的子目錄
路徑可以是字典到涂、zip文件脊框、egg文件颁督。egg文件是由setuptools庫創(chuàng)建的包, 第三方庫常用的格式浇雹。zip文件是添加了元數(shù)據(jù)(版本號(hào)适篙,依賴項(xiàng)等)信息的文件
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1584" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">print(*sys.path, sep='\n')</pre>
sys.path路徑搜索順序?yàn)?/h4>
程序主目錄,程序運(yùn)行主程序腳本所在的目錄文件
PYTHONPATH目錄箫爷,環(huán)境變量PYTHONPATH設(shè)置的目錄
標(biāo)準(zhǔn)庫目錄嚷节,python自帶的庫模塊所在的目錄
第3方庫
模塊會(huì)出現(xiàn)重復(fù)導(dǎo)入嘛?
程序主目錄,程序運(yùn)行主程序腳本所在的目錄文件
PYTHONPATH目錄箫爷,環(huán)境變量PYTHONPATH設(shè)置的目錄
標(biāo)準(zhǔn)庫目錄嚷节,python自帶的庫模塊所在的目錄
第3方庫
模塊不會(huì)存在重復(fù)導(dǎo)入的現(xiàn)象虎锚,所有加載的模塊都會(huì)記錄在sys.modules 中硫痰,
sys.modules是存儲(chǔ)已經(jīng)加載所有模塊的字典,里面包含os, os.path
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1598" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># test1.py
class A:
def showmodule(self):
print(1, self.module, self)
print(2, self.dict)
print(3, self.class.dict)
print(4, self.class.name)
a = A()
a.showmodule()
test2.py
import test1
print('*****')
import test1 # 只能看到一次1窜护,2效斑,3, 4的打印柱徙,只有第一次導(dǎo)入打印了缓屠,
print(sys.modules) # 可以看到test1在里面了。
</pre>
name main
解釋器初始化時(shí)护侮,會(huì)初始化sys.modules字典敌完,然后加載builtins模塊、main模塊羊初、sys模塊滨溉,及sys.path
name
每個(gè)模塊都有這個(gè)特殊變量來存儲(chǔ)當(dāng)前模塊的名稱,如果不指定长赞,則默認(rèn)為源代碼文件名晦攒,如果是包則有限定名。import導(dǎo)入模塊得哆,name默認(rèn)是模塊名脯颜。
當(dāng)從標(biāo)準(zhǔn)輸入(命令行方式巧代碼)、運(yùn)行腳本($ python test.py)贩据、交互式讀取時(shí)栋操,這3種情況都會(huì)將name設(shè)置為main,模塊的頂層代碼在main,這個(gè)作用域中執(zhí)行
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1607" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">if name == 'main':
print('in main')
else:
print('in imported module')</pre>
if name == 'main':作用
對(duì)于非主模塊乐设,測(cè)試本模塊內(nèi)的函數(shù)讼庇、類
-
避免主模塊變更的副作用
頂層代碼沒有封裝,主模塊使用時(shí)沒有問題近尚。但是蠕啄,一旦有了
新的主模塊,舊的主模塊成了被導(dǎo)入模塊,由于原來代碼沒有封裝歼跟,一并執(zhí)行了
模塊屬性
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python " cid="n1618" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">file 源文件絕對(duì)路徑和媳,字符串
name 模塊名
package 如果模塊是包,同name; 否則可以設(shè)置為頂級(jí)模塊的空字符串
spec 顯示模塊規(guī)范
cached 編譯后的字節(jié)碼文件路徑哈街,字符串</pre>
在m1文件中導(dǎo)入m2留瞳,并且查看m2屬性的兩種方法
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1620" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">import m1.m2 as m2 # m1下面同時(shí)存在m2模塊和m2包,找到的是m2包
print(dir(m2)) # 獲得m2的屬性名骚秦,返回列表她倘,如果在m2里面的init文件中,加入屬性B作箍,則可以看到
print('************')
for name in dir(m2):
print(getattr(m2, name))
m2模塊相當(dāng)于一個(gè)字典硬梁,從字典中獲得name屬性。例如:
name doc file等
等價(jià)于
print('***********')
for k, v in m2.dict.items():
print(v)
問題:如果m2中有變量A胞得,為什么dir(m2),看不到A荧止,如果在m2中輸入dir(),就可以看到A阶剑?因?yàn)橄日业降氖莔2包
</pre>
包
- 總結(jié):
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1626" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 如果想在目錄下面寫代碼跃巡,需要寫入目錄下的初始化文件中
當(dāng)目錄作為模塊使用,則會(huì)執(zhí)行初始化文件中的代碼
模塊不是包牧愁,但是素邪,包是一種特殊的模塊
模塊就是命名空間,其內(nèi)部的頂層標(biāo)識(shí)符递宅,都是它的屬性娘香,可以通過dict或者dir(module)查看。</pre>
-
模塊的加載與加入到命名空間的對(duì)比
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1630" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">import sys
import m.m1.m2
print(dir()) # 只有'm'
print(sorted(filter(lambda x: x.startswith('m'), sys.modules.keys())))'m', 'm.m1', 'm.m1.m2'都在办龄,依次加載m,m1,m2的初始化文件
from os import stat
print(dir()) # 沒有osprint(os.path()) # 為什么用不了?os沒在當(dāng)前的命名空間淋昭,雖然os已經(jīng)被加載過了
改成
import os.stat
print(os.path) # 可以使用因?yàn)閛s,加入到了當(dāng)前命名空間了</pre> -
絕對(duì)導(dǎo)入與相對(duì)導(dǎo)入
在包內(nèi)部各個(gè)模塊之間相互調(diào)用俐填,建議使用相對(duì)導(dǎo)入
在包外部使用,包內(nèi)部模塊翔忽,建議使用絕對(duì)導(dǎo)入
-
絕對(duì)導(dǎo)入:import 或者from語句后面沒有. 絕對(duì)導(dǎo)入的搜索順序是英融,
先到sys.modules中查看是否已經(jīng)被加載,被加載直接取出歇式,如果沒有被加載驶悟,則按照sys.path中的順序搜索,然后加載到sys.modules模塊中材失,sys.path的搜索順序是當(dāng)前運(yùn)行模塊的根路徑痕鳍,PYTHONPATH路徑,標(biāo)準(zhǔn)庫和第三方庫。
-
相對(duì)導(dǎo)入:
只能from語句后面有.
1個(gè)點(diǎn)表示當(dāng)前目錄內(nèi)
2個(gè)點(diǎn)表示上一級(jí)目錄
3點(diǎn)表示上上級(jí)目錄
一旦一個(gè)模塊中使用相對(duì)導(dǎo)入笼呆,就不可以作為主模塊運(yùn)行了
相對(duì)導(dǎo)入是為了保證包內(nèi)部資源的相互引用熊响,而不是為了直接運(yùn)行,正確的使用方式是在頂層模塊中使用這些包诗赌。
-
-
- 與all
在模塊m11中定義普通變量汗茄、保護(hù)變量、私有變量铭若、特殊變量:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1661" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">A = 5
_B = 6
__C = 7
my = 8</pre>在模塊m1中導(dǎo)入模塊m11
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1663" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">import m11
print(m11.A, m11._B, m11.__C, m11.my) # 沒有被隱藏都可以訪問也就是說模塊內(nèi)所有變量都不做特殊處理</pre>
如果導(dǎo)入時(shí)使用*:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python " cid="n1665" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 在m1模塊中寫入代碼洪碳,并且運(yùn)行m1
from m11 import * # 問題:?jiǎn)柺裁词褂?m11就不可以呢?
print(dir()) # 只能看到普通變量A叼屠,帶下劃線的都看不到了</pre>如果在模塊m11中加入all, 則all中有什么偶宫,命名空間就有什么變量
all是一個(gè)列表,里面元素是字符串环鲤,每個(gè)元素只能是當(dāng)前模塊中的屬性名纯趋。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1668" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">all = ['A', '_B']
A = 5
_B = 6
__C = 7
my = 8在m1中運(yùn)行
from m11 import *
print(dir()) # ['A', '_B']</pre> -
例子:從頂層模塊訪問包中屬性的方法
如果使用了*, 就盡量使用all, 避免導(dǎo)入過多的模塊,而產(chǎn)生沖突
一般使用from module import name1, name2
已知:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1676" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># m 的init.py中寫入
print(name)
x = 5m1文件中寫入
print(name)
y = 5
</pre>問題:頂層模塊test.py如何訪問到m1中的y冷离?
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1678" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;"># 方法1
在test文件中寫入
from m import m1
print(m1.y)
# 方法2(不可以因?yàn)閙.m1沒在命名空間吵冒,容易錯(cuò)的導(dǎo)入)
import m
print(m.m1.y)
# 方法3
# 在m的__init__文件中寫入 ,__all__ = ['x', 'm1'], __all__中包含的字符串名字是__init__.py中的屬性名,和m包下面的模塊名m1.
from m import *
print(dir()) # ['x', 'm1']
print(m1.y)
# 方法4
# 在m的__init__文件中寫入
# from . import m1
from m import * # __init__.py中有什么變量西剥,就導(dǎo)入了什么變量
print(m1.y)</pre>
-
模塊變量的修改
模塊對(duì)象是同一個(gè)痹栖,因此模塊的變量也是同一個(gè),對(duì)模塊變量的修改會(huì)影響所有的使用該模塊使用者瞭空,特別是常量揪阿,引用類型的還好。
另外可以通過猴子補(bǔ)丁的方式修改模塊的變量咆畏、類南捂、函數(shù)。
打包分發(fā)
使用setup.py打包
在項(xiàng)目根目錄下建立一個(gè)setup.py文件(和m包同級(jí))旧找,在里面填寫腳本
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1688" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">from distutils.core import setup
setup(name='m',
version='1.0',
description='Python test m',
author='JW',
author_email='',
url='',
packages=['m', 'm.m1', 'm.m1.m2'],
)
packages里面填寫溺健,所有包名</pre>
創(chuàng)建源代碼分發(fā)包
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1690" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 在項(xiàng)目根目錄下生成dist文件里面有m-1.0.tar.gz
$ python setup.py sdist
安裝寫好的包,方法1
$ pip install m-1.0.tar.gz
安裝寫好的包,方法2
先解壓,里面含有setup.py文件
$ python setup.py install
</pre>
對(duì)于需要編譯的語言钮蛛,需要先編譯再安裝
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1692" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">$ python setup.py build
會(huì)在根目錄下生成一個(gè)build文件夾鞭缭,在lib下是編譯好的文件</pre>
setup.py生成各種壓縮包的命令
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1695" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"> python setup.py bdist --format=rpm
python setup.py bdist --format=egg
python setup.py bdist_wheel</pre>
插件化開發(fā)
參考筆記10模塊化03插件化開發(fā).pdf
面向?qū)ο笱a(bǔ)充
未實(shí)現(xiàn)和未實(shí)現(xiàn)異常
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1701" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># NotImplemented, 是NotImplementedError實(shí)例,是個(gè)單值魏颓,類似與None
NotImplementedError岭辣,是一個(gè)類
print(type(NotImplemented)) # <class 'NotImplementedType'>
print(type(NotImplementedError)) # <class 'type'></pre>
slots魔術(shù)方法
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1703" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># slots內(nèi)存不夠用時(shí)使用,需要很多實(shí)例甸饱,例如:點(diǎn)類沦童,適用屬性和值都簡(jiǎn)單的類,</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1704" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">使用slots
不可以動(dòng)態(tài)增加屬性
實(shí)例沒有dict屬性了
不影響繼承實(shí)例的字典
class A:
x = 1
slots = ('y', 'z') # 一般用元組
slot = 'y', 'z' # 與上面等價(jià)
slot = ['y', 'z']
slot = 'y' # 也是一個(gè)元組
def init(self):
self.y = 5
self.z = 10
def show(self):
print(self.x, self.y)
a = A()
a.show()
print('A:', A.dict)
print('a:', a.dict) 沒有這個(gè)屬性了
</pre>
slots不影響繼承
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1706" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 繼承
class A:
x = 1
slots = ('y', 'z') # 一般用元組
slot = 'y', 'z' # 與上面等價(jià)
slot = ['y', 'z']
slot = 'y' # 也是一個(gè)元組
def init(self):
self.y = 5
self.z = 10
def show(self):
print(self.x, self.y)
class B(A):
pass
print('********')
b = B()
print('B:', b.dict) # {}
</pre>
內(nèi)建函數(shù)tracemalloc
tracemalloc -Trace memory allocations
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1709" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 內(nèi)建模塊,具體信息參考官方文檔
import tracemalloc
tracemalloc.start() # 開始跟蹤內(nèi)存分配
d = [dict(zip('xy', (5, 6))) for i in range(1000000)] # 237M
t = [tuple(zip('xy', (5, 6))) for i in range(1000000)] # 191M
snapshot = tracemalloc.take_snapshot() # 快照搞动,當(dāng)前內(nèi)存分配
top_stats = snapshot.statistics('lineno') # 快照對(duì)象統(tǒng)計(jì)躏精,按行統(tǒng)計(jì)內(nèi)存
top_stats = snapshot.statistics('filename') # 參看當(dāng)前文件總內(nèi)存
for stat in top_stats:
print(stat)</pre>
運(yùn)算符重載中的反向方法
add 與iadd
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1713" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">class A:
def init(self, x):
self.x = x
def add(self, other):
print('add')
return self.x + other.x
def iadd(self, other):
print('iadd')
return A(self.x + other.x)
def radd(self, other):
print('radd')
if hasattr(other, 'x'):
return self.x + other.x
else:
raise NotImplementedError
def str(self):
return str(self.x)
repr = str
print('***********')
a = A(4)
c = A(5)
print(a + c) # add 9
print(c + a) # add 9
a += c # iadd 9
print(a)
c += a # iadd 9
print(c)
</pre>
調(diào)用iadd的情況,B類中沒有實(shí)現(xiàn)add方法鹦肿,A類中實(shí)現(xiàn)了
radd方法矗烛,想計(jì)算b + a
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1716" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 一種實(shí)現(xiàn)
class A:
def init(self, x):
self.x = x
def add(self, other):
print('add')
return self.x + other.x
def iadd(self, other):
print('iadd')
return A(self.x + other.x)
def radd(self, other):
print('radd')
if hasattr(other, 'x'):
return self.x + other.x
else:
raise NotImplementedError
def str(self):
return str(self.x)
repr = str
class B:
def init(self, x):
self.x = x
def add(self, other):
if isinstance(other, type(self)):
return self.x + other.x
else:
return NotImplemented
a = A(2)
bb = B(3)
print('*************')
print(bb + a) # bb.add(a) 找到NotImplemented, 所以反轉(zhuǎn)計(jì)算a + bb,近而調(diào)用a.radd(bb)
print('+++++++++++')
bb += a # bb沒有iadd 找到add, 拋出NotImplemented,所以找到a.radd
print(bb)
</pre>
另一種實(shí)現(xiàn)
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1718" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">class A:
def init(self, x):
self.x = x
def add(self, other):
print('add')
return self.x + other.x
def iadd(self, other):
print('iadd')
return A(self.x + other.x)
def radd(self, other):
print('radd')
if hasattr(other, 'x'):
return self.x + other.x
else:
raise NotImplementedError
def str(self):
return str(self.x)
repr = str
class B: # 默認(rèn)未實(shí)現(xiàn)add
def init(self, x):
self.x = x
a = A(2)
bb = B(3)
print(bb + a)
print('+++++++++++')
bb += a
print(bb)</pre>
實(shí)現(xiàn) 1 + a
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1720" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 1 + a 方法1
class A:
def init(self, x):
self.x = x
def add(self, other):
print('add')
return self.x + other.x
def iadd(self, other):
print('iadd')
return self.x + other.x
def radd(self, other):
print('radd')
if hasattr(other, 'x'):
return self.x + other.x
elif isinstance(other, int):
return self.x + other
else:
raise NotImplemented
def str(self):
return str(self.x)
repr = str
a1 = A(3)
print(1 + a1) # 1.add(a), 但是這個(gè)加法的返回值是NotImplemented,
解釋器發(fā)現(xiàn)是這個(gè)值箩溃,就發(fā)生反轉(zhuǎn)相當(dāng)于計(jì)算a1 + 1,所以就從a對(duì)象找radd
</pre>
方法2
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1722" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;"># 如果不是整型,返回自己, 1+a 另一種實(shí)現(xiàn)
class A:
def init(self, x):
self.x = x
def add(self, other):
print('add')
return self.x + other.x
def iadd(self, other):
print('iadd')
return self.x + other.x
def radd(self, other):
print('radd')
if hasattr(other, 'x'):
return self.x + other.x
else:
try:
other = int(other)
except ValueError:
other = 0
return self.x + other
def str(self):
return str(self.x)
repr = str
a1 = A(8)
print(1 + a1)
print('abc' + a1)
</pre>
python中的對(duì)象模型
python中任何對(duì)象都有類型瞭吃,可以使用type() 、class查看
繼承所有類都繼承自object涣旨,type類也繼承自object歪架,object的父類是空
python中所有類的類型都是type(元類),實(shí)例的類型是生成實(shí)例的類霹陡。
無參構(gòu)造與值
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n1734" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; background-position: inherit inherit; background-repeat: inherit inherit;">print(None)
print(Exception) # 無參構(gòu)造是一個(gè)類
print(NotImplemented)</pre>