获取类的属性
我想获取一个类的属性,比如说:
class MyClass():
a = "12"
b = "34"
def myfunc(self):
return self.a
使用 MyClass.__dict__
可以让我看到这个类的所有属性和方法,甚至包括像 __module__
和 __doc__
这样的特殊方法。而如果我用 MyClass().__dict__
,得到的结果是一个空的字典,除非我特意给这个实例设置了属性值。
我只想要属性,在上面的例子中,那些属性就是: a
和 b
21 个回答
获取实例属性很简单。
但如果想要获取类属性而不包括函数,就有点复杂了。
仅获取实例属性
如果你只需要列出实例属性,只需使用
for attribute, value in my_instance
.__dict__
.items()
>>> from __future__ import (absolute_import, division, print_function)
>>> class MyClass(object):
... def __init__(self):
... self.a = 2
... self.b = 3
... def print_instance_attributes(self):
... for attribute, value in self.__dict__.items():
... print(attribute, '=', value)
...
>>> my_instance = MyClass()
>>> my_instance.print_instance_attributes()
a = 2
b = 3
>>> for attribute, value in my_instance.__dict__.items():
... print(attribute, '=', value)
...
a = 2
b = 3
获取实例和类属性
要获取类属性而不包括函数,诀窍是使用 callable()
。
但是 静态方法 并不总是 callable
!
因此,使用 callable(value)
的时候,应该改为
callable
(getattr
(MyClass, attribute))
示例
from __future__ import (absolute_import, division, print_function)
class MyClass(object):
a = "12"
b = "34" # class attributes
def __init__(self, c, d):
self.c = c
self.d = d # instance attributes
@staticmethod
def mystatic(): # static method
return MyClass.b
def myfunc(self): # non-static method
return self.a
def print_instance_attributes(self):
print('[instance attributes]')
for attribute, value in self.__dict__.items():
print(attribute, '=', value)
def print_class_attributes(self):
print('[class attributes]')
for attribute in MyClass.__dict__.keys():
if attribute[:2] != '__':
value = getattr(MyClass, attribute)
if not callable(value):
print(attribute, '=', value)
v = MyClass(4,2)
v.print_class_attributes()
v.print_instance_attributes()
注意: print_class_attributes()
应该是 @staticmethod
但在这个 愚蠢而简单 的例子中并不是。
在 python2 中的结果
$ python2 ./print_attributes.py
[class attributes]
a = 12
b = 34
[instance attributes]
c = 4
d = 2
在 python3 中的相同结果
$ python3 ./print_attributes.py
[class attributes]
b = 34
a = 12
[instance attributes]
c = 4
d = 2
这段代码是用来处理一些特定功能的。它可能涉及到一些数据的操作,或者是与用户交互的部分。具体来说,代码块中的内容会根据不同的输入来执行不同的任务。
在编程中,我们常常需要根据条件来决定要做什么,比如如果用户输入了某个值,就执行某个操作;如果输入了另一个值,就执行另一个操作。这种逻辑在代码中是非常常见的。
总之,这段代码的目的是为了让程序能够根据不同的情况做出相应的反应,帮助用户完成他们想要的事情。
def props(cls):
return [i for i in cls.__dict__.keys() if i[:1] != '_']
properties = props(MyClass)
可以试试 inspect 模块。里面的 getmembers
和一些测试功能会很有帮助。
编辑:
举个例子,
class MyClass(object):
a = '12'
b = '34'
def myfunc(self):
return self.a
>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
('__dict__',
<dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'a': '34',
'b': '12',
'myfunc': <function __main__.myfunc>}>),
('__doc__', None),
('__module__', '__main__'),
('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
('a', '34'),
('b', '12')]
现在,那些特殊的方法和属性让我有点烦——处理这些有很多方法,最简单的就是根据名字来过滤。
>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]
……而更复杂的方法可能包括检查特殊属性的名字,甚至使用 metaclasses 哦;)