gpt4 book ai didi

python - 检查python类属性

转载 作者:IT老高 更新时间:2023-10-28 22:08:23 26 4
gpt4 key购买 nike

我需要一种检查类的方法,以便我可以安全地识别哪些属性是用户定义的类属性。问题是 dir()、inspect.getmembers() 和 friend 之类的函数会返回所有类属性,包括预定义的属性,例如:__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)

我花了一些时间尝试通过解析 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 并以相反的顺序遍历它,以便子类键可以覆盖父类(super class)键。它返回一个键值对字典。如果您想要 inspect.getmembers 中的键值元组列表,则只需返回 attrs.items()list(attrs.items()) 在 Python 3 中。

如果您实际上不想遍历 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 - 检查python类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4241171/

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