1. 程式人生 > >Special Attributes Of Class類的特殊屬性

Special Attributes Of Class類的特殊屬性

class 類 特殊屬性

__init__ 初始化方法不要寫任何返回語句,他返回的是你的類的實例

特殊屬性

__name__ 類和函數的名字

__module__ 類定義所在的模塊名

__class__ 對象或類所屬的類

__bases__ 類的基類的元組,按列表出現的順序

__doc__ 類、函數文檔字符串,或None

__mro__ class.mro()返回結果保存

__dict__ 類或實例的屬性

__dir__方法,查看屬性,

返回搜索的內容,盡量多得收集當前模塊的信息,可以從一個實例的類以及祖先類上手機信息。內建函數dir()需要用內置的__dir__方法

  1. dir()

    1. 如果對象什麽都不指定,是模塊對象,收集當前模塊的

    2. 如果指定某個對象,收集指定對象相關的屬性,包括類以及祖先類的屬性。並且去重。

import test2

print(dir())

print(dir(test2))

print(sorted(set(b.__dict.keys()) | set(b.__class__.__dict__.keys()) | set(object.__dict__)))

魔術方法

  1. 創建與銷毀

    1. 創建與銷毀

init__ __del__

  • python 建立了一個dict存儲用來查閱,通過key查閱

用init,添加實例,

  • del與GC回收有關,我們一般不關心。

    1. hash

      1. python將hash用在了可hash類型中,set

      2. 做一個hash散列,hash的時間復雜度是O(1),用在緩存

      3. 緩存的作用是存儲備用,再次使用。

      4. buffer的作用是攔河壩,協調生產者和消費者之間速度差的。

      5. hash 沖突,hash值相同

        1. hash值相同的用set來裝,是否去重

        2. 關系運算 is == 分別有什麽異同

class A:

X = 123

def __init__(self):

self.y = 5

pass

__hash__ = None # # TypeError: unhashable type: 'A'

print(hash(A()))

先調 is 再調 ==

hash一定會有沖突,最簡單用x % 3做 對x hash。可hash並不代表可去重。如果要去重,得看==

c. bool

    1. 就兩條,如果沒有這兩條,那麽就永遠為真的。

      1. 可視化

        1. __repr__ ,與__str__幾乎不區分,如果缺失了__str__就調用__repr__,如果都沒有,就返回object定義,顯示內存地址信息。

        2. __str__,str()函數,返回字符串表達,與repr(),__repr__分先後__repr__,repr()對一個對象獲取字符串表達,調用__repr__方法返回字符串表達,若__repr__沒有定義,就返回object定義,即內存地址信息。

      2. 運算符重載

容器和大小

可調用對象

上下文管理

反射

描述器

其他雜項

__eq__ 判斷是不是相同的,邏輯運算符,return結果是bool

__bool__,若沒有定義__bool__,就調用__len__

技術分享圖片

運算符重載根據實際需求使用。

class A:

def __init__(self, x):

self.x = x

def __sub__(self, other):

return A(self.x - other.x)

def __ne__(self, other):

return self.x != other.x

def __eq__(self, other):

return self.x == other.x

def __lt__(self, other):

return self.x < other.x

def __repr__(self):

return str(self.x)

def __iadd__(self, other):

# self.x += other.x

# return self a1就地修改

return A(self.x + other.x)一個新的a1實例

a1 = A(4)

a2 = A(10)

lst = [a1, a2]

print(sorted(lst))

技術分享圖片

容器方法

技術分享圖片

len 與 size的區別,size指的是容器的大小,len是item的數量。並不相等,大小也不一定。

__len__對應內建函數,len()

__getitem__ 用index或者Key,分別對應使用list,dict ,扔進[ ]一個key,返回對應的item或者value,key不存在KeyError

__setitem__ ,[key],設置一個值給這個key

__missing__ ,類default,

__iter__ 必須返回一個叠代器

用魔術方法實現購物車功能

class Color:

RED = 0

class Item:

def __init__(self, name, **kwargs):

self.name = name

self.__spec = kwargs

def __repr__(self):

return "{} = {}".format(self.name, self.__spec.items()))

class Cart:

def __init__(self):

self.items = []

def additem(self, item:Item):

self.items.append(item)

def getallitems(self):

return self.items

def __getitem__(self, item): # this item is index of items ,Out of range is possible

return Item(self.items[item])

def __missing__(self, key): # dict/set key missing ,list can not use this method

print("key =="key)

def __setitem__(self, key, value):

self.items[key] = value

#self[key] = value 在其他地方可以直接賦值

def __len__(self):

return len(self.items)

def __iter__(self): # 有了這個方法用戶可以直接 for x in cart,而不是for x in cart.items

return iter(self.items)

def __add__(self, other):

if isinstance(other, Item)

self.items.append(other)

class MyDict(dict): #建一個字典類

pass

可調用對象,類的實例調用,相當於調用實例的__call__

為什麽__call__講一個類的實例調用,call的第一個pos args是self

  • 函數foo,foo(5)等價於foo.__call__(5)

__repr__ = __str__ str調用就等於repr調用,所以讓他們

__repr__ = None 讓他的返回值是None 就可以實現相等了

上下文管理

with 開啟一個上下文環境,在接下來的網絡編程中,socket也當文件來用,有上下文

必須是在一個類上去寫,並用在實例上。

class Point:

def __init__(self):

print('init')

def __enter__(self): # 維護了文件資源

print(self.__class__)

return self

def __exit__(self, exc_type, exc_val, exc_tb): #

print(self.__class__.__name__)

p = Point()

import sys

with Point() as f:

print(p == f)

print(p is f)

需要給__enter__ return 一個適當的值,給f

exc_type

exc_val

exc_tb 返回類True的話,壓制異常

技術分享圖片

技術分享圖片

上下文的應用場景

  1. 增強功能

    1. 在代碼執行的前後增加代碼,類似裝飾器的功能。

  2. 資源管理

    1. 文件對象、網絡連接、數據庫連接等的關閉

  3. 權限驗證

    1. 權限驗證,在__enter__z中處理

技術分享圖片

add存在與TImeIT的實例C()的參數中,add函數定義不存在了

contextlib.contextmanager

是一個裝飾器,也可以實現上下文管理。對函數有要求,必須是一個生成器函數。

yield雖然在字節碼上和return有區別,但是可以把它當成return看。

import contextlib

@contextlib.contextmanager

def foo():

print('enter')

yield 3,5 # 必須有yield語句,在yield的發生處切一刀,前後加東西,把yield的返回值放到enter裏面,作為返回值。

print('exit')

with foo() as f:

try:

raise Exception

finally:

print(f)

functools @total_ordering ,如果註重效率,就最好不要用。

加上total_ordering用來減少操作,比如定義eq,用total_ordering推演其他比較,如果沒有@total無法對進行其他比較。


Special Attributes Of Class類的特殊屬性