我经常使用成语'{var_name}'.format(**vars(some_class))
。
但是,当我使用属性时,我无法使用它来获取属性值。
考虑这个程序:
#!/usr/bin/env python
class Foo(object):
def __init__(self):
self._bar = None
self.baz = 'baz here'
@property
def bar(self):
if not self._bar:
# calculate some value...
self._bar = 'bar here'
return self._bar
if __name__ == '__main__':
foo = Foo()
# works:
print('{baz}'.format(**vars(foo)))
# gives: KeyError: 'bar'
print('{bar}'.format(**vars(foo)))
问题:
有没有办法通过**vars(some_class)
访问属性值?
答案 0 :(得分:4)
简短回答:不,不可能使用.format(**vars(object))
来执行您想要的操作,因为属性不使用__dict__
和vars
文档:
vars(...)
vars([object])
- >字典
- 没有参数,相当于
locals()
。- 使用参数,相当于
object.__dict__
。
但是,您可以使用不同的格式说明符来实现所需的目的,例如属性查找:
In [2]: '{.bar}'.format(Foo())
Out[2]: 'bar here'
请注意,您只需在名称中添加前导.
(点)即可获得所需内容。
附注:不应使用.format(**vars(object))
,而应使用format_map
方法:
In [6]: '{baz}'.format_map(vars(Foo()))
Out[6]: 'baz here'
使用format_map
参数调用dict
相当于使用format
表示法调用**
,但效率更高,因为它不需要执行任何操作在调用函数之前解压缩。
答案 1 :(得分:1)
使用.
表示法 -
print('{0._bar}'.format(foo))
答案 2 :(得分:1)
要完全按照您的要求进行操作,您可以编写一个将项目访问权限转换为属性访问权限的类:
class WrapperDict(object):
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
return getattr(self.obj, key)
示例:
>>> print('{bar}'.format_map(WrapperDict(Foo())))
bar here
另一个相当黑客的选择是添加
__getitem__ = object.__getattribute__
到班级Foo
,然后直接使用Foo
个实例:
>>> print('{bar}'.format_map(Foo()))
bar here
我认为使用属性访问表示法是更好的解决方案。
答案 3 :(得分:0)
如果我理解你是对的,那么这样的事情应该有效:
print( eval( 'foo.{bar}'.format( **dict( ( v, v ) for v in dir( foo ) ) ) ) )
但不过这感觉“非常糟糕”。
答案 4 :(得分:0)
您可以将其写入实例的__dict__
class Article(object):
def __init__(self):
self.content = ""
self.url = ""
@property
def title(self):
return self.__dict__.get("title", "")
@title.setter
def title(self, title):
self.__dict__["title"] = title
然后:
>>> article = Article()
>>> article.title = "Awesome Title"
>>> vars(article)
{'content': '', 'url': '', 'title': 'Awesome Title'}