Rumah > pembangunan bahagian belakang > Tutorial Python > Mengapa Saya Tidak Boleh Menggunakan `property()` dengan Classmethods dalam Python dan Apakah Penyelesaiannya?

Mengapa Saya Tidak Boleh Menggunakan `property()` dengan Classmethods dalam Python dan Apakah Penyelesaiannya?

DDD
Lepaskan: 2024-12-12 21:28:12
asal
300 orang telah melayarinya

Why Can't I Use `property()` with Classmethods in Python, and What Are the Workarounds?

Menggunakan property() dengan kaedah kelas: Penerokaan

Dalam Python, fungsi property() memainkan peranan penting dalam mencipta getter dan setter untuk atribut kelas. Walau bagaimanapun, percubaan untuk menggunakan property() dengan classmethods, yang dihiasi dengan @classmethod decorator, boleh membawa kepada ralat yang tidak dijangka.

Mari kita pertimbangkan coretan kod berikut yang menggambarkan isu ini:

class Foo(object):
    _var = 5

    @classmethod
    def getvar(cls):
        return cls._var

    @classmethod
    def setvar(cls, value):
        cls._var = value

    var = property(getvar, setvar)
Salin selepas log masuk

Apabila cuba mengakses atau menetapkan atribut var pada contoh kelas Foo, kami menghadapi ralat:

>>> f = Foo()
>>> f.getvar()
5
>>> f.setvar(4)
>>> f.getvar()
4
>>> f.var
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'classmethod' object is not callable
Salin selepas log masuk

Seperti yang dijelaskan dalam dokumentasi dan dalam perbincangan Limpahan tindanan [Kaedah Kelas Python sebagai Setter dan Getter](https://stackoverflow.com/questions/27906399/python-class-method-as -setter-and-getter), tidak mungkin untuk menggunakan fungsi property() dengan classmethods dalam Python 3.8 dan lebih awal.

Walau bagaimanapun, terdapat pendekatan alternatif untuk mencapai kefungsian yang diingini:

Untuk Python 2 dan Python 3 (termasuk 3.9-3.10):

Memandangkan sifat mempengaruhi contoh, tetapi sifat kelas dicipta pada kelas, adalah perlu untuk mencipta sifat pada metaclass.

class Foo(object):
    _var = 5

    class __metaclass__(type):  # Python 2 syntax for metaclasses
        pass

    @classmethod
    def getvar(cls):
        return cls._var

    @classmethod
    def setvar(cls, value):
        cls._var = value

Foo.__metaclass__.var = property(Foo.getvar.im_func, Foo.setvar.im_func)
Salin selepas log masuk

Untuk versi Python dari 3.9 dan seterusnya:

Penyelesaian yang lebih bersih melibatkan mengalihkan kaedah kelas ke metaclass dan mengisytiharkan harta secara terus pada metaclass:

class Foo_meta(type):
    @property
    def var(cls):
        return cls._var

    @var.setter
    def var(cls, value):
        cls._var = value

class Foo(metaclass=Foo_meta):
    _var = 5
Salin selepas log masuk

Kaedah alternatif ini secara berkesan membenarkan penggunaan peringkat kelas hartanah.

Atas ialah kandungan terperinci Mengapa Saya Tidak Boleh Menggunakan `property()` dengan Classmethods dalam Python dan Apakah Penyelesaiannya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan