当前位置: 首页 > 面试题库 >

检查python类属性

孙光临
2023-03-14
问题内容

我需要一种检查类的方法,以便可以安全地标识哪些属性是用户定义的类属性。问题是,像DIR功能(),inspect.getmembers()和朋友返回所有类的属性包括预定义的像:__class____doc____dict____hash__。这当然是可以理解的,并且可以说我可以列出一个要忽略的命名成员列表,但是不幸的是,这些预定义属性必定会随着不同版本的Python发生变化,因此使我的项目在python项目中容易发生变化-
我不喜欢那样。

例:

>>> class A:
...   a=10
...   b=20
...   def __init__(self):
...     self.c=30
>>> dir(A)
['__doc__', '__init__', '__module__', 'a', 'b']
>>> get_user_attributes(A)
['a','b']

在上面的示例中,我想要一种仅检索用户定义的类属性[‘a’,’b’]而不是’c’的安全方法,因为它是实例属性。所以我的问题是…有人可以通过上述虚构功能来帮助我get_user_attributes(cls)吗?

PS我花了一些时间尝试通过在AST级别解析类来解决问题,这非常容易。但是我找不到将已解析的对象转换为AST节点树的方法。我猜一旦类被编译成字节码,所有的AST信息都会被丢弃。

最好的问候雅各布


问题答案:

下面是困难的方法。这是简单的方法。不知道为什么我早就没想到。

import inspect

def get_user_attributes(cls):
    boring = dir(type('dummy', (object,), {}))
    return [item
            for item in inspect.getmembers(cls)
            if item[0] not in boring]

这是一个开始

def get_user_attributes(cls):
    boring = dir(type('dummy', (object,), {}))
    attrs = {}
    bases = reversed(inspect.getmro(cls))   
    for base in bases:
        if hasattr(base, '__dict__'):
            attrs.update(base.__dict__)
        elif hasattr(base, '__slots__'):
            if hasattr(base, base.__slots__[0]): 
                # We're dealing with a non-string sequence or one char string
                for item in base.__slots__:
                    attrs[item] = getattr(base, item)
            else: 
                # We're dealing with a single identifier as a string
                attrs[base.__slots__] = getattr(base, base.__slots__)
    for key in boring:
        del attrs['key']  # we can be sure it will be present so no need to guard this
    return attrs

这应该相当健壮。本质上,它通过获取object要忽略的默认子类上的属性来工作。然后,它获取传递给它的类的mro并以相反的顺序遍历它,以便子类键可以覆盖超类键。它返回键值对的字典。如果您想要一个键列表,inspect.getmembers则使用in中的值元组,然后在Python
3中返回attrs.items()list(attrs.items())

如果您实际上并不想遍历mro,而只想直接在子类上定义属性,那么它会更容易:

def get_user_attributes(cls):
    boring = dir(type('dummy', (object,), {}))
    if hasattr(cls, '__dict__'):
        attrs = cls.__dict__.copy()
    elif hasattr(cls, '__slots__'):
        if hasattr(base, base.__slots__[0]): 
            # We're dealing with a non-string sequence or one char string
            for item in base.__slots__:
                attrs[item] = getattr(base, item)
            else: 
                # We're dealing with a single identifier as a string
                attrs[base.__slots__] = getattr(base, base.__slots__)
    for key in boring:
        del attrs['key']  # we can be sure it will be present so no need to guard this
    return attrs


 类似资料:
  • 我正在寻找一种在python中构建类的方法: setter在赋值前检查值的类型 暂时我找到了那两个装修师: 和 但我很难加入这两种方法。你能帮助我吗?你有什么想法吗?谢谢

  • 问题内容: 我有一个值列表和bin边缘列表。现在,我需要检查所有值属于它们的bin。除了遍历值然后遍历bin并检查该值是否属于当前bin之外,还有没有比Python更有效的方法了,例如: 对我来说,这看起来并不漂亮。谢谢! 问题答案: 可能为时已晚,但为将来参考,numpy具有执行此操作的功能: http://docs.scipy.org/doc/numpy/reference/generated

  • 问题内容: 如果我有字典,并且想检查一下,则可以将其作为一个块(非常好!),也可以使用方法作为默认值。 我想为做同样的事情。也就是说,如果尚未设置对象,我已经有要返回的对象,但这给了我类似的错误 AttributeError:’bool’对象没有属性’attribute’ 问题答案: 更直接的类似物比是。 (在哪里是可选的,如果未找到,则在no属性上引发异常。) 例如,您将通过。

  • 我使用以下断言,但失败了。这是在AssertJ中测试JSON的正确方法吗。

  • 属性检查器 是我们查看并编辑当前选中节点、节点组件和资源的工作区域。在 场景编辑器、层级管理器 中选中节点或者在 资源管理器 中选中资源,就会在 属性检查器 中显示它们的属性,可供查询和编辑。 节点名称和激活开关 左上角的复选框表示节点的激活状态,使用节点处于非激活状态时,节点上所有图像渲染相关的组件都会被关闭,整个节点包括子节点就会被有效的隐藏。 节点激活开关右边显示的是节点的名称,和 层级管理

  • 属性检查器 是我们查看并编辑节点或资源属性的重要渠道。可编辑节点的位置,节点上的组件,图片,材质,模型等资源,面板功能细节多,较为复杂。 在 场景编辑器 ,层级管理器 选中节点,或者在 资源管理器 选中资源,就能在 属性检查器 中显示并开始编辑它的属性。 头部公共部分 左边的 两个箭头 是历史记录,点击可切换编辑项; 右边的 锁图标 可锁定面板,固定住编辑的对象,不让面板随新的选中项而变动。 编辑