मान लीजिए हम निम्नलिखित वर्ग पदानुक्रम है: अगर मैं ऐसा तरह ClassB पर __ __ dict का पता लगानेक्या __dict__ (या ऐसा कुछ) तक पहुंचने का कोई तरीका है जिसमें बेस क्लास शामिल हैं?
class ClassA:
@property
def foo(self): return "hello"
class ClassB(ClassA):
@property
def bar(self): return "world"
, मैं सिर्फ बार विशेषता देखें:
for name,_ in ClassB.__dict__.items():
if name.startswith("__"):
continue
print(name)
आउटपुट बार
हैमैं न केवल निर्दिष्ट प्रकार बल्कि इसके पूर्वजों पर विशेषताओं को प्राप्त करने के लिए अपने स्वयं के साधन रोल कर सकता हूं। हालांकि, मेरा सवाल यह है कि क्या मेरे लिए एक पहिया का पुन: आविष्कार किए बिना ऐसा करने के लिए पहले से ही पाइथन में एक तरीका है।
def return_attributes_including_inherited(type):
results = []
return_attributes_including_inherited_helper(type,results)
return results
def return_attributes_including_inherited_helper(type,attributes):
for name,attribute_as_object in type.__dict__.items():
if name.startswith("__"):
continue
attributes.append(name)
for base_type in type.__bases__:
return_attributes_including_inherited_helper(base_type,attributes)
मेरे कोड चल रहा है इस प्रकार है ...
for attribute_name in return_attributes_including_inherited(ClassB):
print(attribute_name)
... दोनों बार और foo वापस देता है।
ध्यान दें कि मैं कुछ चीजों को सरल बना रहा हूं: आइटम टकराव, वस्तुओं का उपयोग करके() इस उदाहरण के लिए जब मैं __ से शुरू होने वाली किसी भी चीज पर छोड़ देता हूं, तो संभावना है कि दो पूर्वजों के पास एक आम पूर्वज है, आदि।
EDIT1 - मैंने उदाहरण को सरल रखने की कोशिश की। लेकिन मैं वास्तव में प्रत्येक वर्ग और पूर्वजों वर्ग के लिए विशेषता नाम और विशेषता संदर्भ दोनों चाहता हूं। नीचे दिए गए उत्तरों में से एक ने मुझे एक बेहतर ट्रैक पर रखा है, जब मैं इसे काम करने के लिए कुछ बेहतर कोड पोस्ट करूंगा।
EDIT2 - यह वही करता है जो मैं चाहता हूं और बहुत संक्षिप्त है। यह नीचे एली के जवाब पर आधारित है।
def get_attributes(type):
attributes = set(type.__dict__.items())
for type in type.__mro__:
attributes.update(type.__dict__.items())
return attributes
यह विशेषता नाम और उनके संदर्भ दोनों को वापस देता है।
EDIT3 - inspect.getmembers का उपयोग करके सुझाए गए उत्तरों में से एक। यह बहुत उपयोगी प्रतीत होता है क्योंकि यह केवल ताना की तरह है, यह केवल पूर्वजों के वर्गों पर भी चलता है।
class MyCustomDescriptor:
# This is greatly oversimplified
def __init__(self,foo,bar):
self._foo = foo
self._bar = bar
pass
def __call__(self,decorated_function):
return self
def __get__(self,instance,type):
if not instance:
return self
return 10
class ClassA:
@property
def foo(self): return "hello"
@MyCustomDescriptor(foo="a",bar="b")
def bar(self): pass
@MyCustomDescriptor(foo="c",bar="d")
def baz(self): pass
class ClassB(ClassA):
@property
def something_we_dont_care_about(self): return "world"
@MyCustomDescriptor(foo="e",bar="f")
def blah(self): pass
# This will get attributes on the specified type (class) that are of matching_attribute_type. It just returns the attributes themselves, not their names.
def get_attributes_of_matching_type(type,matching_attribute_type):
return_value = []
for member in inspect.getmembers(type):
member_name = member[0]
member_instance = member[1]
if isinstance(member_instance,matching_attribute_type):
return_value.append(member_instance)
return return_value
# This will return a dictionary of name & instance of attributes on type that are of matching_attribute_type (useful when you're looking for attributes marked with a particular descriptor)
def get_attribute_name_and_instance_of_matching_type(type,matching_attribute_type):
return_value = {}
for member in inspect.getmembers(ClassB):
member_name = member[0]
member_instance = member[1]
if isinstance(member_instance,matching_attribute_type):
return_value[member_name] = member_instance
return return_value
वास्तव में क्या आप एक बार तुम्हारे पास है विशेषता सूची के साथ क्या करने जा रहे हैं? –
प्रश्न में कक्षाएं संदेश का प्रतिनिधित्व करती हैं जो deserialized किया गया है। संदेश फ़ील्ड साझा करते समय विरासत का उपयोग करते हैं। एक विधि है जिसे प्रत्येक संदेश के प्रत्येक फ़ील्ड के बारे में जानकारी प्रिंट करने की आवश्यकता होती है। इन संदेश वर्गों की प्रत्येक विशेषता वास्तव में एक वर्णक के साथ चिह्नित की जाती है लेकिन मैंने उस विवरण को छोड़ दिया क्योंकि मैंने सोचा था कि यह अप्रासंगिक था। –
... तो, वर्णनकर्ता को अद्यतन करें ताकि यह वर्णित विशेषता को किसी सूची में जोड़ सके? या - और यह थोड़ा बहुत कट्टरपंथी हो सकता है - अलग-अलग गुणों के बजाय स्ट्रिंग कुंजियों वाला एक नियम का उपयोग करें? –