Python, 理解下面这个装饰器(based on class), 有哪几个关键点 ?
怪我咯
怪我咯 2017-04-18 10:33:42
0
2
484
class memoized_property(object):
    """A read-only @property that is only evaluated once."""

    def __init__(self, fget, doc=None):
        self.fget = fget
        self.__doc__ = doc or fget.__doc__
        self.__name__ = fget.__name__

    # 这个方法应该是这个缓存装饰器的关键
    # 因此, 我组织关键字如下
    #     * python __get__
    #     * how python __get__ works
    #     # python descript tools
    def __get__(self, obj, cls):
        if obj is None:
            return self
        obj.__dict__[self.__name__] = result = self.fget(obj)
        return result

    def _reset(self, obj):
        memoized_property.reset(obj, self.__name__)

    @classmethod
    def reset(cls, obj, name):
        obj.__dict__.pop(name, None)
怪我咯
怪我咯

走同样的路,发现不同的人生

membalas semua(2)
洪涛

Menurut kaedah pelaksanaan memoized_property, jawapan berikut semuanya mempunyai premis, iaitu, diandaikan ia digunakan sebagai penghias untuk fungsi kelas. Pada ketika ini kelas ini boleh dianggap sebagai versi pengubahsuaian penghias hartanah. Kesan caching boleh dicapai kerana Python mempunyai keutamaan apabila mengakses atribut .

Untuk a.val, Python melakukan pemprosesan berikut:

  1. mula-mula mengakses __dict__ objek, iaitu, a.__dict__['val'];

  2. Jika tiada
  3. untuk mengakses kelas sekali lagi, ia akan mencari ke atas sepanjang hubungan warisan;

    A.__dict__['val']Jika

    ditemui dan nilai dikembalikan, maka nilai itu diperoleh; jika deskriptor dikembalikan, kaedah
  4. deskriptor akan dipanggil;
  5. Untuk A.__dict__['val'] di sini: __get__

    Sebagai contoh, kelas ini merangkum fungsi val kelas A:
  6. class A(object):
        ...
        
        @memoized_property
        def val(self):
            ...
    
    a = A()
    a.val
    
Apabila mengakses

buat kali pertama, mengikut urutan carian di atas: ia tidak ditemui dalam objek, lompat ke langkah kedua; ia ditemui dalam kamus kelas, tetapi ia didapati sebagai deskriptor , jadi ia akan memasukkan deskriptor dalam kaedah memoized_property. Di sini, selepas menggunakan

untuk memanggil fungsi

yang dihias dan mengira hasilnya, sambil mengembalikan hasilnya, hasilnya juga disimpan dalam

. Pada kali seterusnya anda melawat

, memandangkan terdapat val dalam __get__ objek, ia akan mencari self.fget(obj) terlebih dahulu dan bukannya berusaha habis-habisan untuk mencari val. Ini mencapai kesan cache atribut. obj.__dict__['val'] am tidak akan menetapkan a.val, jadi ia akan dikira semula setiap kali. __dict__ valSelepas memahami perkara ini, obj.__dict__['val'] ia sangat jelas, cuma alih keluar laluan dengan keutamaan sebelumnya. Kemudian Python terpaksa mencari langkah demi langkah di sepanjang keutamaan dan mendapati bahawa __get__ tersedia, jadi ia memanggil kaedah __get__ di dalamnya dan mengira semula sekali lagi. obj.__dict__['xxx']

Dan bahagian dalam

boleh dikatakan jauh lebih baik. . . . reset

Ty80

Kaedah kelas ialah kaedah yang anda boleh panggil terus tanpa membuat seketika kelas

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan