cari

Rumah  >  Soal Jawab  >  teks badan

Python, 理解下面这个装饰器(based on class), 有哪几个关键点 ?

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)
怪我咯怪我咯2837 hari yang lalu507

membalas semua(2)saya akan balas

  • PHP中文网

    PHP中文网2017-04-18 10:35:42

    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

    balas
    0
  • PHP中文网

    PHP中文网2017-04-18 10:35:42

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

    balas
    0
  • Batalbalas