python進階篇--property和itemgetter的魔法

property() 很容易理解, itemgetter也很容易理解。但是當兩者相遇的時候就擦出了魔法的火花。

先來看一段代碼。

import operator


class StructTupleMeta(type):
    def __init__(cls, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(cls)
        for n, name in enumerate(cls._fields):
            setattr(cls, name, property(operator.itemgetter(n)))


class StructTuple(tuple, metaclass=StructTupleMeta):
    _fields = []

    def __new__(cls, *args, **kwargs):
        if len(args) != len(cls._fields):
            raise ValueError("The arg number is not right")
        return super().__new__(cls, args)


class Stock(StructTuple):
    _fields = ['name', 'shares', 'price']

    def __getitem__(self, item):
        print("__getitem__", [0])


if __name__ == "__main__":
    stock = Stock("abc", 10, 20)
    print(stock.name)

注意一下StructTupleMeta下面兩句話
for n, name in enumerate(cls._fields):
setattr(cls, name, property(operator.itemgetter(n)))

這裏看起來很簡單,但是卻包含很多東西。
這句話的功能是,給類cls添加一個屬性。屬性的getter函數是operator.itemgetter(0)。 有點想不通的是,operaor.itemgetter(0)返回的是可調用對象,需要傳參才能使用。比如

f=operator.itemgetter(0). a = [1,2,3]
c = f(a)

上一段代碼的結果應該是 1,即返回a[0].
那麼問題來了,類中的屬性的getter函數時operator.itemgetter(0). 這個函數的參數時如何傳進去的?
看一下官網的解釋.
Return a callable object that fetches item from its operand using the operand’s getitem() method. If multiple items are specified, returns a tuple of lookup values. For example:
其實operaor.itemgetter本質上時調用對象的__getitem__ 函數。這樣就說的通了。stock.name 本質上調用的時 stock的__getitem__ 函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章