簡體   English   中英

如何覆蓋類似dict的對象的屬性設置?

[英]How can I override property setting for a dict-like object?

我正在編寫C綁定,並且要包裝的C結構具有一些字符串索引的屬性值。

我想將這些作為python中的dict公開。

到目前為止,我有一個函數get_properties ,該函數以單個字典形式返回對象的所有屬性。 我使用property函數將其包裝在類定義中,以便可以將其作為類屬性進行訪問:

(在類中定義)

class MyClass:
    def get_properties(self):
        ...
    properties = property(get_properties)

(例)

>>> print myobj.properties
{'test': 5, 'test2': 'string'}

現在,我想以類似dict的方式來設置它們。 我有一個名為set_property的C函數的包裝函數,該函數具有字符串鍵和幾種類型的值。

我嘗試從類property使用set_properties

class MyClass:
    def get_properties(self):
        ...
    def set_property(self, key, value):
        ...
    def set_properties(self, props):
        [self.set_property(k, props[k]) for k in props]
    properties = property(get_properties, set_properties)

如下所示:

>>> myobj.properties = {"test3": 6}
>>> print myobj.properties
{'test': 5, 'test2': 'string', 'test3': 6}

但是,您可以看到,這並不完全是預期的行為。 我更喜歡的是:

>>> myobj.properties['test3'] = 6

我嘗試為properties添加__setitem__的定義:

class MyClass:
    ...
    properties = property(get_properties)
    properties.__setitem__ = set_property

但這讓我

AttributeError: 'property' object has no attribute '__setitem__'

我試圖使屬性成為dict,並簡單地覆蓋__setitem____getitem__但是它沒有它。

知道這樣做的正確方法是什么嗎? 我可以使類property表現得像字典嗎?

謝謝。

好的,Mike的回答給了我解決這個問題的想法,方法是使用擴展的dict類從屬性的getter返回,在該類中,我根據上下文覆蓋了__setitem__

class MyClass(object):
    def get_properties():
        ... (call C function and convert to dict)
    def set_property():
        ... (call C function)
    def propgetter(self):
        context = self
        props = self.get_properties()
        class propsetter(dict):
            __getitem__ = props.__getitem__
            def __setitem__(self, key, value):
                props[key] = value
                context.set_property(key, value)
        return propsetter(self.get_properties())
    properties = property(propgetter)

看起來像我想要的那樣工作。

您定義屬性的方式是只讀的。 但是,屬性裝飾器實際上可以選擇使用set和get函數:

class MyClass(object):
    def __init__(self):
        self.d = {"hello":None}
    def __repr__(self):
        return "%s"%(self.d,)
    def get(self):
        return self.d
    def set(self, value):
        self.d = value
    x = property(get, set)

通過為內部字典定義setter,您現在可以在其上設置鍵:

>>> c = MyClass()
>>> c.x
{'hello': None}
>>> c.x["hello"] = "world"
>>> c.x
{'hello': 'world'}
>>> c.x = {"key":"value"}
>>> c.x
{'key': 'value'}

另外,如果您使用的是Python(2.6+)的最新版本,則可以使用如下裝飾器來編寫這種更好的方法:

class MyClass():
    def __init__(self):
        self.d = {"hello":None}
    def __repr__(self):
        return "%s"%(self.d,)
    @property
    def x(self):
        return self.d
    @x.setter
    def set(self, value):
        self.d = value

暫無
暫無

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

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