क्या क्लासमेथोड सजाया कार्यों के साथ संपत्ति () फ़ंक्शन का उपयोग करना संभव है?
नहीं।
हालाँकि, एक classmethod उस वर्ग के उदाहरणों से सुलभ एक वर्ग पर एक बाउंड मेथड (आंशिक कार्य) है।
चूंकि उदाहरण वर्ग का एक कार्य है और आप कक्षा को उदाहरण से प्राप्त कर सकते हैं, इसलिए आप वर्ग-संपत्ति से जो भी वांछित व्यवहार प्राप्त कर सकते हैं उसे प्राप्त कर सकते हैं property
:
class Example(object):
_class_property = None
@property
def class_property(self):
return self._class_property
@class_property.setter
def class_property(self, value):
type(self)._class_property = value
@class_property.deleter
def class_property(self):
del type(self)._class_property
इस कोड का उपयोग परीक्षण करने के लिए किया जा सकता है - इसे बिना किसी त्रुटि के पास करना चाहिए:
ex1 = Example()
ex2 = Example()
ex1.class_property = None
ex2.class_property = 'Example'
assert ex1.class_property is ex2.class_property
del ex2.class_property
assert not hasattr(ex1, 'class_property')
और ध्यान दें कि हमें मेटाक्लास की बिल्कुल भी आवश्यकता नहीं थी - और आप सीधे अपनी कक्षाओं के माध्यमों से मेटाक्लास तक नहीं पहुँच सकते हैं।
@classproperty
डेकोरेटर लिखना
आप वास्तव classproperty
में उप-वर्ग द्वारा कोड की कुछ पंक्तियों में एक डेकोरेटर बना सकते हैं property
(यह सी में लागू है, लेकिन आप यहां बराबर पायथन देख सकते हैं ):
class classproperty(property):
def __get__(self, obj, objtype=None):
return super(classproperty, self).__get__(objtype)
def __set__(self, obj, value):
super(classproperty, self).__set__(type(obj), value)
def __delete__(self, obj):
super(classproperty, self).__delete__(type(obj))
फिर डेकोरेटर का इलाज करें जैसे कि वह एक संपत्ति के साथ एक वर्गमोहक था:
class Foo(object):
_bar = 5
@classproperty
def bar(cls):
"""this is the bar attribute - each subclass of Foo gets its own.
Lookups should follow the method resolution order.
"""
return cls._bar
@bar.setter
def bar(cls, value):
cls._bar = value
@bar.deleter
def bar(cls):
del cls._bar
और यह कोड त्रुटियों के बिना काम करना चाहिए:
def main():
f = Foo()
print(f.bar)
f.bar = 4
print(f.bar)
del f.bar
try:
f.bar
except AttributeError:
pass
else:
raise RuntimeError('f.bar must have worked - inconceivable!')
help(f) # includes the Foo.bar help.
f.bar = 5
class Bar(Foo):
"a subclass of Foo, nothing more"
help(Bar) # includes the Foo.bar help!
b = Bar()
b.bar = 'baz'
print(b.bar) # prints baz
del b.bar
print(b.bar) # prints 5 - looked up from Foo!
if __name__ == '__main__':
main()
लेकिन मुझे यकीन नहीं है कि यह कितना अच्छा होगा। एक पुराना मेलिंग सूची लेख बताता है कि उसे काम नहीं करना चाहिए।
वर्ग पर काम करने के लिए संपत्ति प्राप्त करना:
ऊपर का नकारात्मक पक्ष यह है कि "वर्ग संपत्ति" वर्ग से सुलभ नहीं है, क्योंकि यह बस वर्ग से डेटा डिस्क्रिप्टर को अधिलेखित कर देगा __dict__
।
हालाँकि, हम मेटाक्लस में परिभाषित संपत्ति के साथ इसे ओवरराइड कर सकते हैं __dict__
। उदाहरण के लिए:
class MetaWithFooClassProperty(type):
@property
def foo(cls):
"""The foo property is a function of the class -
in this case, the trivial case of the identity function.
"""
return cls
और फिर मेटाक्लास का एक वर्ग उदाहरण में एक संपत्ति हो सकती है जो पहले से पहले अनुभागों में प्रदर्शित सिद्धांत का उपयोग करके वर्ग की संपत्ति तक पहुंचती है:
class FooClassProperty(metaclass=MetaWithFooClassProperty):
@property
def foo(self):
"""access the class's property"""
return type(self).foo
और अब हम दोनों उदाहरण देखते हैं
>>> FooClassProperty().foo
<class '__main__.FooClassProperty'>
और वर्ग
>>> FooClassProperty.foo
<class '__main__.FooClassProperty'>
वर्ग की संपत्ति तक पहुँच है।