2017-02-24 67 views
2

我一直在使用namedlist創建簡單的類:如何查看python命名列表對象上的屬性?

from namedlist import namedlist 
# create a class 
SomeClass = namedlist('SomeClass', 'foo bar', use_slots=False) 

# create an object 
my_list = SomeClass(1,2) 

# set an attribute not specified in the class 
my_list.baz = 3 

# the attribute is there if I reference it 
print(my_list.baz) 
# output: 3 

有時我要帶一個對象,並看看是否有任何額外的屬性被設置:

# this doesn't show 'baz' 
import inspect 
inspect.getmembers(my_list) 

# neither does this 
my_list.__dict__ 

有沒有一種方法,我可以看到以這種方式添加的任何屬性?

+0

屬性尚未添加,只是[**'__getattr__' **](https://docs.python.org/2 /reference/datamodel.html#object.__getattr__)已被重載。 –

回答

1

查看namedlist的來源,我們可以看到工廠函數namedlist()生成類型(在您的示例中爲SomeClass)。

現在這很有趣。

一方面,__getattribute____setattribute__沒有超載,它可以讓你做的事情一樣my_list.baz = 3,然後訪問它my_list.baz

另一方面,__dict__property(_asdict)覆蓋(生成於_common_fields())。這會導致使用__dict__的用戶無法看到baz - 功能,如dir()inspect模塊。

雖然我沒能找到一個函數,將列出在這種情況下,添加的屬性,如果你知道什麼屬性,你所尋找的,你仍然可以檢查是否存在使用hasattr(my_list, 'baz')

>>> from namedlist import namedlist 
>>> SomeClass = namedlist('SomeClass', 'foo bar', use_slots=False) 
>>> my_list = SomeClass(1,2) 
>>> my_list.baz = 3 
>>> hasattr(my_list, 'baz') 
True 
0

如果切換類型將是有問題的(也許有舊代碼已經在使用namedlist),我發現下面使用戶在觀看namedlist忍受:

def set_attr(self, attr_name, attr_val): 
     setattr(self, attr_name, attr_val) 
     self.opt_attrs.append(attr_name) 

    TypeA = namedlist('TypeA', 'field_a opt_attrs', use_slots=False) 
    TypeA.set_attr = set_attr 

    TypeB = namedlist('TypeB', 'field_b opt_attrs', use_slots=False) 
    TypeB.set_attr = set_attr 

    objA = TypeA(1, []) 
    objA.set_attr('field_x', 2) 

    objB = TypeB(7, []) 

objA 
# Out: TypeA(field_a=1, opt_attrs=['field_x']) 

objA.field_x 
# Out: 2 

objB 
# Out: TypeB(field_b=7, opt_attrs=[]) 

這可能是最好的只是雖然使用Python類。更多的預先編碼,更少的事後混淆:

class TypeA: 
    def __init__(self, a): 
     self.a = a 
    def __repr__(self): 
     return "A(a={})".format(self.a) 

class TypeB: 
    def __init__(self, b): 
     self.b = b 
    def __repr__(self): 
     return "B(b={})".format(self.b) 

A = TypeA(1) 
A.x = 2 

B = TypeB(7) 

class TypeA: 
    def __init__(self, a): 
     self.a = a 
    def __repr__(self): 
     return "A(a={})".format(self.a) 

class TypeB: 
    def __init__(self, b): 
     self.b = b 
    def __repr__(self): 
     return "B(b={})".format(self.b) 

objA = TypeA(1) 
objA.x = 2 

objB = TypeB(7) 

objA 
# Out: A(a=1) 

objA.__dict__ 
# Out: {'a': 1, 'x': 2} 

objB 
# Out: B(b=7) 
相關問題