是否有访问__dict__(或类似的东西),包括基类的方法吗? [英] Is there a way to access __dict__ (or something like it) that includes base classes?

查看:130
本文介绍了是否有访问__dict__(或类似的东西),包括基类的方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 类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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆