2017-02-24 69 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) 
相关问题