从内省角度来看,有一种方法可以在不创建实例的情况下获取类实例变量。创建实例时很容易:
class Super:
def __init__(self, name):
self.name = name
class Sub(Super):
pass
a = Super("Nice_Name")
print(a.__dict__.keys())
但我希望在不创建实例的情况下获取该信息,只是为了内省。有办法吗?
答案 0 :(得分:0)
不,你不能,因为python不是statically typed language,所以在实例化对象之前,该对象没有类型。例如,想象一下这样的类:
class A:
def __init__(self):
self.a = "a"
def change_type(self):
self.a = 1
在实例化对象之前,self.a
的类型是什么?如果需要内省,则不能使用python。
答案 1 :(得分:0)
我一直在对此进行一些研究,在某些情况下您可以可以执行此操作,但是还没有完美的解决方案:
@property
装饰符定义实例变量,那么在执行dir(class_type)
时它将显示出来。__slots__
魔术变量定义实例属性的允许列表,然后只需执行class_type.__slots__
即可获取实例变量。self.varname = expression
的任何引用。当然,这假设self
将始终是引用类实例的方式,并且在诸如内部类或将self
重新分配给另一个varname的情况下会失败。同样也不会选择setattr(self, varname, expression)
之类的东西,您需要其他逻辑来进行检测。ast
模块并将其用于解析类源代码。然后进行一些搜索以查找可能将属性写入类self
的表达式。查看此示例:
import dill, re
class Test:
__slots__ = ["x","y","z"]
def __init__(self):
self.x = 0
self.y = 1
self.z = 2
@property
def q(self):
return self.x
# this grabs those defined using __slots__ or @property
print(dir(Test))
# this looks at class source
# may need to play around with the regex more...
s = dill.source.getsource(Test)
var_finder = re.compile("self\.([^\W]+)\s*\=")
print(set(var_finder.findall(s)))
我个人认为在课堂上添加__slots__
是最好的方法。对于sphinx文档(这是我的用例),这似乎是获取autosummary
指令以提取这些实例变量的最佳方法。