簡體   English   中英

我可以在python 3中為描述符定義add方法嗎?

[英]Can I define an add method for a descriptor in python 3?

我在這里引用了python文檔,以了解如何在python中創建已控制getter和setter方法的類屬性。 https://docs.python.org/3/howto/descriptor.html#id6

我使用以下代碼創建了描述符屬性類:

class PropNumberString(object):
    def __init__(self, initval=None, name='var_int'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print("in getter")
        return self.val

    def __set__(self, obj, val):
        print("in setter")
        self.val = int(val)

    def __add__(self, val):
        print("adding")
        print("val to add: ", val)
        self.val = int(self.val) + int(val)
        return self

    def __radd__(self, val):
        return self.__add__(val)


class ConnectionTemplate(object):
    tid = PropNumberString(0, "ID")

我也嘗試定義一個add方法,即使提供了一個字符串,它也總是要添加一個整數。 這不起作用,似乎調用了“ __get__”,然后調用了返回的整數的add方法,而不是我的add方法。

這是一個測試以證明:

my_template = ConnectionTemplate()

print("Getting value")
print(my_template.tid)

print("Updating value")
my_template.tid = 100

print("Doing add")
my_template.tid = my_template.tid + "1"

print(my_template.tid)
print("type: ", type(my_template.tid))

輸出:

Getting value
in getter
0
Updating value
in setter
Doing add
in getter
Traceback (most recent call last):
  File "connection_template.py", line 53, in <module>
    my_template.tid = my_template.tid + "1"
TypeError: unsupported operand type(s) for +: 'int' and 'str'

有一個好的解決方案嗎?

編輯:這就是我最終要做的事,其中包含了Alex Hall提供的答案

class StrInt(int):
    def __add__(self, val):
        return StrInt(super().__add__(int(val)))
    __radd__ = __add__

class PropNumberString(object):
    def __init__(self, val=None, name='var_name'):
        self.val = StrInt(val)
        self.name = name

    def __get__(self, obj, objtype):
        return self.val

    def __set__(self, obj, val):
        self.val = StrInt(val)

class ConnectionTemplate(object):
    tid_field = "ID"

    def __init__(self, tid=0):
        self.tid = PropNumberString(tid, self.ansa_tid_field)

    def __getattribute__(self, key):
        # see https://docs.python.org/3/howto/descriptor.html#id5
        "Emulate type_getattro() in Objects/typeobject.c"
        attrib = object.__getattribute__(self, key)
        if hasattr(attrib, '__get__'):
            return attrib.__get__(None, self)
        return attrib

    def __setattr__(self, key, val):
        try:
            attrib = object.__getattribute__(self, key)
        except AttributeError:
            self.__dict__[key] = val
            return
        if hasattr(attrib, '__set__'):
            attrib.__set__(None, val)
            return
        self.__dict__[key] = val

注意:我使用自定義描述符而不是屬性裝飾器的動機是,我希望我的屬性能夠包含自定義元數據,即json轉儲的鍵值。

您無需為此定義自定義描述符。 您只需要tid返回一個添加所需方式的類即可。 最好是在設置而不是獲取時進行轉換。 這是一個實現:

class MyInt(int):
    def __add__(self, val):
        return MyInt(super().__add__(int(val)))

    __radd__ = __add__


class ConnectionTemplate(object):
    def __init__(self):
        self._tid = 0

    @property
    def tid(self):
        return self._tid

    @tid.setter
    def tid(self, val):
        self._tid = MyInt(val)

暫無
暫無

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

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