簡體   English   中英

使用雙星號(**)實現屬性

[英]Implementing a property using the double asterisk (**)

http://www.programiz.com/python-programming/property之后,我熟悉以下在Python中實現屬性的方法:

class Celsius(object):
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def get_temperature(self):
        print("Getting value")
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

    temperature = property(get_temperature, set_temperature)

我現在正在閱讀一些代碼,其中使用雙星號( ** )來定義屬性。 如果我將其調整為適合自己的示例,則它看起來像這樣:

class Celsius(object):
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def temperature():
        def fget(self):
            print("Getting value")
            return self._temperature
        def fset(self, value):
            if value < -273:
                raise ValueError("Temperature below -273 is not possible")
            print("Setting value")
            self._temperature = value

    temperature = property(**temperature())

但是,如果我嘗試運行此代碼並通過c = Celsius()實例化一個類,則會得到

TypeError: type object argument after ** must be a mapping, not NoneType

據我所知, fgetfset是關鍵字參數property ,所以我希望什么出來的**temperature()是像fget=fget, fset=fset ,但我不知道這到底是怎么還是走錯了如何進一步剖析。 有任何想法嗎?

您應該return嵌套函數,然后根據函數調用將其解壓縮:

class Celsius(object):
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def temperature():
        ...
        return fget, fset

    temperature = property(*temperature())

如果您堅持使用** ,那么您將從函數中返回映射/字典,然后將其解壓縮為關鍵字參數。

def temperature():
    ...
    return {'fget': fget, 'fset': fset}

temperature = property(**temperature())

之所以會出現此錯誤,是因為temperature()調用返回None ,然后您嘗試使用**將其解包為字典。 因此,要使該代碼正常工作,您需要返回一個包含setter和getter方法的適當字典。

我更喜歡Moses的解決方案,但是如果您確實願意, 可以使用dict而不是元組傳遞方法。 例如,

class Celsius(object):
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def temperature():
        def fget(self):
            print("Getting value")
            return self._temperature
        def fset(self, value):
            if value < -273:
                raise ValueError("Temperature below -273 is not possible")
            print("Setting value")
            self._temperature = value
        return {'fget': fget, 'fset': fset}

    temperature = property(**temperature())

# Test
a = Celsius()
a.temperature = 20
print(a.temperature)

產量

Setting value
Getting value
20

確實,我錯過了temperature函數定義中的return語句。 原始代碼實際上包含該行

return locals()

添加此行使該屬性按預期工作。

您定義的temperature方法沒有return語句,因此它隱式返回None ,這是錯誤消息中的...,not NoneType 該方法確實有兩個子方法,但是這不會導致它以任何形式返回它們,我認為您缺少諸如(untested)之類的行:

return { "fget": fget, "fset": fset }

您還可以使用一個列表和一個*

話雖如此,這是避免***魔術的最佳實踐,也有防止這種情況的柔道規則

暫無
暫無

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

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