gpt4 book ai didi

python - 有没有办法访问包含基类的 __dict__ (或类似的东西)?

转载 作者:太空狗 更新时间:2023-10-29 18:00:29 24 4
gpt4 key购买 nike

假设我们有以下类层次结构:

class ClassA:

@property
def foo(self): return "hello"

class ClassB(ClassA):

@property
def bar(self): return "world"

如果我像这样在 ClassB 上探索 __dict__,我只会看到 bar 属性:

for name,_ in ClassB.__dict__.items():

if name.startswith("__"):
continue

print(name)

输出是条

我可以使用自己的方法来获取指定类型及其祖先的属性。但是,我的问题是 python 中是否已经有一种方法可以让我在不重新发明轮子的情况下做到这一点。

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)

... 返回 bar 和 foo。

请注意,我正在简化一些事情:名称冲突、在本示例中我可以使用字典时使用 items()、跳过任何以 __ 开头的内容、忽略两个祖先本身具有共同祖先的可能性等。

EDIT1 - 我试图让示例保持简单。但我真的想要每个类和祖先类的属性名称和属性引用。下面的答案之一让我走上了更好的轨道,当我让它工作时,我会发布一些更好的代码。

EDIT2 - 这是我想要的,而且非常简洁。它基于以下 Eli 的回答。

def get_attributes(type):

attributes = set(type.__dict__.items())

for type in type.__mro__:
attributes.update(type.__dict__.items())

return attributes

它返回属性名称及其引用。

EDIT3 - 下面的答案之一建议使用 inspect.getmembers。这看起来非常有用,因为它就像 dict 一样,只是它也对祖先类进行操作。

由于我尝试做的大部分工作是查找标有特定描述符的属性,并包括祖先类,因此这里有一些代码可以帮助您做到这一点,以防对任何人有帮助:

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

最佳答案

您应该使用 python 的 inspect 模块来实现任何此类内省(introspection)功能。

.
.
>>> 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>)

阅读更多关于 inspect 模块的信息 here .

关于python - 有没有办法访问包含基类的 __dict__ (或类似的东西)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8529192/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com