python面向?qū)ο?

簡(jiǎn)單例子1

內(nèi)建函數(shù)setattr() getattr() hasattr() 即使類中沒有setattrgetattr魔術(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異常

  1. 它的return值將作為屬性查找的結(jié)果

  2. 如果拋出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 = content

    def 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)入嘛?

模塊不會(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()) # 沒有os

    print(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 = 5

    m1文件中寫入

    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 sdist python setup.py bdist --format=rpm
python setup.py bdist --format=gztar python setup.py bdist --format=egg
python setup.py bdist --format=wheel 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í)例的類霹陡。

類型與繼承.png

無參構(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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末和蚪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子烹棉,更是在濱河造成了極大的恐慌攒霹,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浆洗,死亡現(xiàn)場(chǎng)離奇詭異催束,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伏社,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門抠刺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摘昌,你說我怎么就攤上這事速妖。” “怎么了第焰?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵买优,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我挺举,道長(zhǎng),這世上最難降的妖魔是什么烘跺? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任湘纵,我火速辦了婚禮,結(jié)果婚禮上滤淳,老公的妹妹穿的比我還像新娘梧喷。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布铺敌。 她就那樣靜靜地躺著汇歹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪偿凭。 梳的紋絲不亂的頭發(fā)上产弹,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音弯囊,去河邊找鬼痰哨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛匾嘱,可吹牛的內(nèi)容都是我干的斤斧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼霎烙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼撬讽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悬垃,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤游昼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盗忱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酱床,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年趟佃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扇谣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闲昭,死狀恐怖罐寨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情序矩,我是刑警寧澤鸯绿,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站簸淀,受9級(jí)特大地震影響瓶蝴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜租幕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一舷手、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劲绪,春花似錦男窟、人聲如沸盆赤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺六。三九已至嗡载,卻和暖如春采郎,著一層夾襖步出監(jiān)牢的瞬間死陆,已是汗流浹背捉貌。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工碗短, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迅细,地道東北人朱盐。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓涝缝,卻偏偏與公主長(zhǎng)得像台囱,于是被迫代替她去往敵國(guó)和親淡溯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容