Python 对象继承自省
Python Introspection with Object Inheritance
我正在使用 python 的旧版本 2.6.5。我可以使用 dir 查看对象有哪些成员,但我想区分对象中的成员与从父对象继承的成员 class。
class Parent(object):
def parent_method1(self):
return 1
def parent_method2(self):
return 2
class Child(Parent):
def child_method1(self):
return 1
有没有办法检查(即 dir)Child 对象的实例并区分哪些方法来自 Child class,哪些方法继承自 Parent class?
不,dir()
没有区别。
您必须手动遍历 class MRO 并自己生成列表:
def dir_with_context(cls):
for c in cls.__mro__:
for name in sorted(c.__dict__):
yield (c, name)
这会产生:
>>> list(dir_with_context(Child))
[(<class '__main__.Child'>, '__doc__'), (<class '__main__.Child'>, '__module__'), (<class '__main__.Child'>, 'child_method1'), (<class '__main__.Parent'>, '__dict__'), (<class '__main__.Parent'>, '__doc__'), (<class '__main__.Parent'>, '__module__'), (<class '__main__.Parent'>, '__weakref__'), (<class '__main__.Parent'>, 'parent_method1'), (<class '__main__.Parent'>, 'parent_method2'), (<type 'object'>, '__class__'), (<type 'object'>, '__delattr__'), (<type 'object'>, '__doc__'), (<type 'object'>, '__format__'), (<type 'object'>, '__getattribute__'), (<type 'object'>, '__hash__'), (<type 'object'>, '__init__'), (<type 'object'>, '__new__'), (<type 'object'>, '__reduce__'), (<type 'object'>, '__reduce_ex__'), (<type 'object'>, '__repr__'), (<type 'object'>, '__setattr__'), (<type 'object'>, '__sizeof__'), (<type 'object'>, '__str__'), (<type 'object'>, '__subclasshook__')]
该函数可以很容易地扩充以跳过子class中已经出现的名称:
def dir_with_context(cls):
seen = set()
for c in cls.__mro__:
for name in sorted(c.__dict__):
if name not in seen:
yield (c, name)
seen.add(name)
此时它生成的条目数与 dir(Child)
完全相同,除了名称出现的顺序(以上按 class 分组):
>>> sorted(name for c, name in dir_with_context(Child)) == dir(Child)
True
我正在使用 python 的旧版本 2.6.5。我可以使用 dir 查看对象有哪些成员,但我想区分对象中的成员与从父对象继承的成员 class。
class Parent(object):
def parent_method1(self):
return 1
def parent_method2(self):
return 2
class Child(Parent):
def child_method1(self):
return 1
有没有办法检查(即 dir)Child 对象的实例并区分哪些方法来自 Child class,哪些方法继承自 Parent class?
不,dir()
没有区别。
您必须手动遍历 class MRO 并自己生成列表:
def dir_with_context(cls):
for c in cls.__mro__:
for name in sorted(c.__dict__):
yield (c, name)
这会产生:
>>> list(dir_with_context(Child))
[(<class '__main__.Child'>, '__doc__'), (<class '__main__.Child'>, '__module__'), (<class '__main__.Child'>, 'child_method1'), (<class '__main__.Parent'>, '__dict__'), (<class '__main__.Parent'>, '__doc__'), (<class '__main__.Parent'>, '__module__'), (<class '__main__.Parent'>, '__weakref__'), (<class '__main__.Parent'>, 'parent_method1'), (<class '__main__.Parent'>, 'parent_method2'), (<type 'object'>, '__class__'), (<type 'object'>, '__delattr__'), (<type 'object'>, '__doc__'), (<type 'object'>, '__format__'), (<type 'object'>, '__getattribute__'), (<type 'object'>, '__hash__'), (<type 'object'>, '__init__'), (<type 'object'>, '__new__'), (<type 'object'>, '__reduce__'), (<type 'object'>, '__reduce_ex__'), (<type 'object'>, '__repr__'), (<type 'object'>, '__setattr__'), (<type 'object'>, '__sizeof__'), (<type 'object'>, '__str__'), (<type 'object'>, '__subclasshook__')]
该函数可以很容易地扩充以跳过子class中已经出现的名称:
def dir_with_context(cls):
seen = set()
for c in cls.__mro__:
for name in sorted(c.__dict__):
if name not in seen:
yield (c, name)
seen.add(name)
此时它生成的条目数与 dir(Child)
完全相同,除了名称出现的顺序(以上按 class 分组):
>>> sorted(name for c, name in dir_with_context(Child)) == dir(Child)
True