Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Adakah terdapat penghias yang setara dengan `@property` dalam Python untuk menentukan harta kelas?

Adakah terdapat penghias yang setara dengan `@property` dalam Python untuk menentukan harta kelas?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-11 00:52:03576semak imbas

Is there a decorator equivalent to `@property` in Python for defining a class property?

Cara Mentakrifkan Harta Kelas dalam Python

Dalam Python, penghias @classmethod boleh digunakan untuk menambah kaedah pada kelas. Walau bagaimanapun, adakah terdapat penghias yang setara untuk mentakrifkan harta untuk kelas?

Penghias Harta Kelas

Untuk menjawab soalan ini, mari kita pertimbangkan contoh berikut:

class Example(object):
    the_I = 10

    def __init__(self):
        self.an_i = 20

    @property
    def i(self):
        return self.an_i

    def inc_i(self):
        self.an_i += 1

    # is this even possible?
    @classproperty
    def I(cls):
        return cls.the_I

    @classmethod
    def inc_I(cls):
        cls.the_I += 1

e = Example()
assert e.i == 20
e.inc_i()
assert e.i == 21

assert Example.I == 10
Example.inc_I()
assert Example.I == 11

Dalam contoh ini, tujuannya adalah untuk mentakrifkan sifat kelas saya menggunakan penghias @classproperty. Walau bagaimanapun, ralat "NameError: nama 'classproperty' tidak ditakrifkan" dinaikkan.

Penyelesaian

Untuk mencipta sifat kelas, kelas deskriptor tersuai yang dipanggil ClassPropertyDescriptor boleh digunakan:

import inspect

class ClassPropertyDescriptor(object):

    def __init__(self, fget, fset=None):
        self.fget = fget
        self.fset = fset

    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        return self.fget.__get__(obj, klass)()

    def __set__(self, obj, value):
        if not self.fset:
            raise AttributeError("can't set attribute")

        if inspect.isclass(obj):
            type_ = obj
            obj = None
        else:
            type_ = type(obj)

        return self.fset.__get__(obj, type_)(value)

    def setter(self, func):
        if not isinstance(func, (classmethod, staticmethod)):
            func = classmethod(func)
        self.fset = func
        return self

Kelas ClassPropertyDescriptor mentakrifkan kelakuan harta kelas. Ia melaksanakan kaedah __get__ dan __set__ untuk mengendalikan mendapatkan dan menetapkan nilai harta benda.

Penghias Harta Kelas

Untuk memudahkan penggunaan deskriptor sifat kelas, penghias dipanggil @ classproperty boleh dibuat:

def classproperty(func):
    if not isinstance(func, (classmethod, staticmethod)):
        func = classmethod(func)

    return ClassPropertyDescriptor(func)

Contoh Penggunaan

Dengan adanya deskriptor dan penghias harta kelas tersuai, contoh boleh ditulis semula sebagai:

class Bar(object):

    _bar = 1

    @classproperty
    def bar(cls):
        return cls._bar

    @bar.setter
    def bar(cls, value):
        cls._bar = value

Kod ini mentakrifkan bar sifat kelas yang boleh diakses dan diubah suai seperti yang diharapkan. Mengubah suai nilai sifat pada tika kelas atau kelas itu sendiri akan mengemas kini nilai untuk semua tika kelas.

Atas ialah kandungan terperinci Adakah terdapat penghias yang setara dengan `@property` dalam Python untuk menentukan harta kelas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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