通過“學習 Python:強大的面向物件編程”作業
第 28 章讓您創建了一個類,該類將列出物件的所有實體屬性。
然后這本書提供了一些想法,例如列出繼承樹上的所有屬性。這樣做時,我使用了@classmethod下面顯示的裝飾器 - 并且想知道是否有辦法將這些型別的方法從我的串列中過濾出來:
"""Assorted class utilities and tools"""
class ShowAttrs(object):
"""
A class to show all available (including inherited, excluding special) attributes
"""
@classmethod
def getAttrs(cls, child_cls):
my_attrs = [_ for _ in child_cls.__dict__ if _.startswith('_') is False]
my_name = child_cls.__name__
listed_attrs = [my_name ': ' ', '.join(my_attrs)]
try:
bases = child_cls.__bases__
inherited_attrs = []
for base in bases[::-1]:
if base.__name__ != 'ShowAttrs' and base.__name__ != 'object':
inherited_lists = [ShowAttrs.getAttrs(base)]
for _ in inherited_lists:
inherited_attrs.extend(_)
except NameError:
return
inherited_attrs.extend(listed_attrs)
return inherited_attrs
def __repr__(self):
child_cls = self.__class__
all_attrs = ShowAttrs.getAttrs(child_cls)
len_attrs = reversed(list(range(len(all_attrs))))
all_attrs_unique = [ x for i,x in zip(len_attrs,all_attrs[::-1]) if i <= all_attrs.index(x) ]
return '\n'.join(reversed(all_attrs_unique))
if __name__ == '__main__':
class Parent(ShowAttrs):
var3 = 'Parent'
def parentMethod(self):
print('this is a Parent')
class Child(Parent):
var2 = 'Child'
def childMethod(self):
print('this is a Child')
class GrandChild(Child):
var1 = 'GrandChild'
@classmethod
def howCanIFilterThisOneOut(cls):
pass
def grandchildMethod(self):
print('this is a GrandChild')
def grandchildMethod2(self):
pass
def grandchildMethod3(self):
pass
class GrandChild2(Child):
var11 = 'GrandChild2'
class GreatGrandChild(GrandChild, GrandChild2):
var0 = 'GreatGrandChild'
x = GreatGrandChild()
print(x)
當我運行這個:
Python 3 x = GreatGrandChild() 列印(x)
Console
Parent: var3, parentMethod
Child: var2, childMethod
GrandChild2: var11
GrandChild: var1,howCanIFilterThisOneOut, grandchildMethod, grandchildMethod2, grandchildMethod3
GreatGrandChild: var0
但是howCanIFilterThisOneOut是類方法,而不是實體方法。所以只是想知道是否可以區分。
謝謝
沙箱試一試: https ://edube.org/sandbox/af4390bc-77aa-11ec-ab3f-0242157e55ca
uj5u.com熱心網友回復:
isinstance(x, classmethod) 成功了。
my_attrs = [
name for (name, value)
in child_cls.__dict__.items()
if not name.startswith('_') and not isinstance(value, classmethod)
]
順便說一句,您的代碼可以通過重復洗掉等簡化為類似
import inspect
def get_fields(cls):
seen = set()
for cls in inspect.getmro(cls)[::-1]:
if cls is object:
continue
attr_names = {
name
for name in cls.__dict__
if name not in seen and not name.startswith("_")
}
seen.update(attr_names)
yield (cls.__name__, sorted(attr_names))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/414268.html
標籤:
上一篇:覆寫類引數Python
下一篇:這個組合關系的例子是否正確?
