是否有访问__dict__(或类似的东西),包括基类的方法吗? [英] Is there a way to access __dict__ (or something like it) that includes base classes?
问题描述
假设我们有下面的类层次结构:
类ClassA的: @属性
高清富(个体经营):回归你好类ClassB的(ClassA的): @属性
高清杆(个体经营):回归世界
如果我探索的 __ 字典 __ 在ClassB的像这样,我只看到了吧属性:
的名称,在_ .__ ClassB的字典__项目(): 如果name.startswith(__):
继续 打印(名称)
输出为栏
我可以推出自己的手段,不仅指定的类型,但它的祖先获取属性。不过,我的问题是,是否有已在python办法为我做到这一点不重新发明轮子。
高清return_attributes_including_inherited(类型):
结果= []
return_attributes_including_inherited_helper(类型,结果)
返回结果高清return_attributes_including_inherited_helper(类型,属性): 对于名称,attribute_as_object型.__字典__项目(): 如果name.startswith(__):
继续 attributes.append(名) 在类型.__ bases__ base_type:
return_attributes_including_inherited_helper(base_type,属性)
运行我的code如下...
在return_attributes_including_inherited(ClassB的)ATTRIBUTE_NAME:
打印(ATTRIBUTE_NAME)
...还给两个酒吧和富。
请注意,我简化了一些事情:名称冲突,使用的物品()时,在这个例子中,我可以用字典,跳过任何以__开始,无视的可能性,两个祖先的本身有一个共同的祖先,等等。
EDIT1 - 我试图保持例子简单。但我真的希望两个属性名和为每个类和祖先类的属性引用。下面一个问题的答案我有一个更好的轨道,我会后一些更好的code,当我得到它的工作。
EDIT2 - 这我想要做什么,是非常简洁。它是基于以下伊莱的答案。
高清get_attributes(类型): 属性=集(类型.__字典__。项目()) 在类型.__ mro__类型:
attributes.update(键入.__字典__。项目()) 返回属性
据还给这两个属性名称和它们的引用。
EDIT3 - 答案之一使用inspect.getmembers以下建议。因为它像字典这似乎非常有用的,只有它的祖先类操作为好。
由于什么,我试图做一个大的部分是找到标有特定的描述符属性,包括祖先类,这里是一些code,这将有助于做到这一点的情况下,它可以帮助任何人:
类MyCustomDescriptor: #这是极大的过于简单 高清__init __(自我,富,吧):
self._foo = foo的
self._bar =酒吧
通过 高清__call __(自我,decorated_function):
自回归 高清__get __(自我,例如,类型): 如果没有实例:
自回归 返回10类ClassA的: @属性
高清富(个体经营):回归你好 @MyCustomDescriptor(富=A,酒吧=B)
高清杆(个体经营):通 @MyCustomDescriptor(富=C,酒吧=D)
高清巴兹(个体经营):通类ClassB的(ClassA的): @属性
高清something_we_dont_care_about(个体经营):回归世界 @MyCustomDescriptor(富=E,酒吧=F)
高清等等(个体经营):通#这将让指定的类型(类),它们matching_attribute_type的属性。它只是返回的属性本身,而不是自己的名字。
高清get_attributes_of_matching_type(类型,matching_attribute_type): RETURN_VALUE = [] 会员在inspect.getmembers(类型): MEMBER_NAME =成员[0]
member_instance =成员[1] 如果isinstance(member_instance,matching_attribute_type):
return_value.append(member_instance) 回报RETURN_VALUE#这将返回名称和放大器的字典;上式是matching_attribute_type的(有用的,当你正在寻找标有特定的描述符属性)的属性实例
高清get_attribute_name_and_instance_of_matching_type(类型,matching_attribute_type): RETURN_VALUE = {} 为成员inspect.getmembers(ClassB的): MEMBER_NAME =成员[0]
member_instance =成员[1] 如果isinstance(member_instance,matching_attribute_type):
RETURN_VALUE [MEMBER_NAME] = member_instance 回报RETURN_VALUE
您应该使用Python的检查
模块任何这样的自省能力。
。
。
>>>类ClassC(ClassB的):
... DEF巴兹(个体经营):
...回归你好
...
>>>进口检查
>>>在inspect.getmembers ATTR(ClassC):
...打印ATTR
...
('__doc__',无)
('__module__','__main__')
('酒吧',<在0x10046bf70&GT财产对象;)
(巴兹,<未绑定的方法ClassC.baz>)
('富',<在0x10046bf18&GT财产对象;)
Suppose we have the following class hierarchy:
class ClassA:
@property
def foo(self): return "hello"
class ClassB(ClassA):
@property
def bar(self): return "world"
If I explore __dict__ on ClassB like so, I only see the bar attribute:
for name,_ in ClassB.__dict__.items():
if name.startswith("__"):
continue
print(name)
Output is bar
I can roll my own means to get attributes on not only the specified type but its ancestors. However, my question is whether there's already a way in python for me to do this without re-inventing a wheel.
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)
Running my code as follows...
for attribute_name in return_attributes_including_inherited(ClassB):
print(attribute_name)
... gives back both bar and foo.
Note that I'm simplifying some things: name collisions, using items() when for this example I could use dict, skipping over anything that starts with __, ignoring the possibility that two ancestors themselves have a common ancestor, etc.
EDIT1 - I tried to keep the example simple. But I really want both the attribute name and the attribute reference for each class and ancestor class. One of the answers below has me on a better track, I'll post some better code when I get it to work.
EDIT2 - This does what I want and is very succinct. It's based on Eli's answer below.
def get_attributes(type):
attributes = set(type.__dict__.items())
for type in type.__mro__:
attributes.update(type.__dict__.items())
return attributes
It gives back both the attribute names and their references.
EDIT3 - One of the answers below suggested using inspect.getmembers. This appears very useful because it's like dict only it operates on ancestor classes as well.
Since a large part of what I was trying to do was find attributes marked with a particular descriptor, and include ancestors classes, here is some code that would help do that in case it helps anyone:
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
You should use python's inspect
module for any such introspective capabilities.
.
.
>>> class ClassC(ClassB):
... def baz(self):
... return "hiya"
...
>>> import inspect
>>> for attr in inspect.getmembers(ClassC):
... print attr
...
('__doc__', None)
('__module__', '__main__')
('bar', <property object at 0x10046bf70>)
('baz', <unbound method ClassC.baz>)
('foo', <property object at 0x10046bf18>)
Read more about the inspect
module here.
这篇关于是否有访问__dict__(或类似的东西),包括基类的方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!