簡體   English   中英

Python:通過**變量(some_class)訪問只讀屬性

[英]Python: Making a read-only property accessible via **vars(some_class)

我經常使用成語'{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)訪問屬性值?

簡短回答:不,不可能使用.format(**vars(object))來做你想做的事情,因為屬性使用__dict__並且來自vars文檔:

vars(...)

vars([object]) - >字典

  • 沒有參數,相當於locals()
  • 有一個參數,相當於object.__dict__

但是,您可以使用不同的格式說明符來實現所需的目的,例如屬性查找:

In [2]: '{.bar}'.format(Foo())
Out[2]: 'bar here'

請注意,您只需添加一個前導. (點)到名字,你得到你想要的。


旁注:您應該使用format_map方法,而不是使用.format(**vars(object))

In [6]: '{baz}'.format_map(vars(Foo()))
Out[6]: 'baz here'

使用dict參數調用format_map相當於使用**表示法調用format ,但它更有效,因為它在調用函數之前不必進行任何類型的解包。

使用. 符號 -

print('{0._bar}'.format(foo))

要完全按照您的要求進行操作,您可以編寫一個將項目訪問權限轉換為屬性訪問權限的類:

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

另一個相當hacky的替代方案是添加

__getitem__ = object.__getattribute__

到類Foo然后直接使用Foo實例:

>>> print('{bar}'.format_map(Foo()))
bar here

我認為使用屬性訪問符號是更好的解決方案。

如果我理解你是對的,這樣的事情應該有效:

print( eval( 'foo.{bar}'.format( **dict( ( v, v ) for v in dir( foo ) ) ) ) )

但不過這感覺“非常糟糕”。

您可以將其寫入實例的__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'}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM