2017-06-22 94 views
0

我有一个构造函数接受*kwargs的对象,并将它们设置为属性。用python文字创建对象的字符串表示形式

class Observable(object): 
    def __init__(self, **kwargs): 
     for key in kwargs.keys(): 
      setattr(self, key, kwargs[key]) 

我想打印表示通过以下方式对象:

>>> obs = Observable(foo=1, bar=5, _bazz=12, name='Amok', props=('One', 'two')) 
>>> print(x) 
Observable(bar=5, foo=1, name='Amok', props=('One', 'two')) 

我尝试添加自定义__repr__

class Observable(object): 
    def __init__(self, **kwargs): 
     for key in kwargs.keys(): 
      setattr(self, key, kwargs[key]) 

    def __repr__(self): 
     atribs = [(atrib, self.__dict__[atrib]) for atrib in self.__dict__.keys() if not '_' == atrib[0]] 
     atrib_strs = [] 
     for atrib, val in atribs: 
      atrib_strs.append('{}={}'.format(atrib, val)) 

     out_str = '{}({})'.format(self.__class__.__name__, ', '.join(atrib_strs)) 
     return out_str 

对于输入它上面打印:

Observable(foo=1, bar=5, name=Amok, props=('One', 'two')) 

我担心的是我有Amok而不是'Amok'。 我可以添加一个字符串的类型检查,但也许有一种方法来获得任何python类型的正确字符串表示形式?也许一个标准的库函数?

+1

我还没有看到这个问题,但我的ocd正在杀死我看* pytonically *而不是pythonic或pythonically *。 – void

+0

@s_vishnu谢谢,修正了 – Euphe

+0

HAHA很好的伴侣。等待我尝试一个解决方案 – void

回答

3

完成此操作的一种简单方法是通过repr()调用每个属性的值__repr__()。这样,每个字符串表示是 保证要显示。

>>> class Observable(object): 
    def __init__(self, **kwargs): 
     for key in kwargs.keys(): 
      setattr(self, key, kwargs[key]) 

    def __repr__(self): 
     atribs = [(atrib, self.__dict__[atrib]) for atrib in self.__dict__.keys() if not '_' == atrib[0]] 
     atrib_strs = [] 
     for atrib, val in atribs: 
      atrib_strs.append('{}={}'.format(atrib, repr(val))) # add repr() call 

     out_str = '{}({})'.format(self.__class__.__name__, ', '.join(atrib_strs)) 
     return out_str 

>>> ob = Observable(foo=1, bar=5, _bazz=12, name='Amok', props=('One', 'two')) 
>>> print(ob) 
Observable(foo=1, name='Amok', props=('One', 'two'), bar=5) 
>>> 
+0

如何不使用'dict.keys' /获取值并使用'dict.items' /'dict.iteritems'来代替? –

+1

@AzatIbrakov因为他不想在表示中包含“私有”变量。尽管他的代码可以改进,但我并没有真正尝试。 –