【问题标题】:Repeating decorators for instance variables实例变量的重复装饰器
【发布时间】:2020-07-08 17:58:31
【问题描述】:

我正在编写一个类,我需要检查实例变量是否属于某种类型。

我注意到有很多重复的代码。 有没有更好的方法对实例变量进行类似检查? 或者这是正确的做法?

class Variable():

    __type = 'Variable'

    def __init__(self, id = None, updateable = True, name = 'Variable', value=None):
        if id is not None:
            self.id = id
        if value is not None:
            self.value = value
        self.updateable = updateable
        self.name = name

    @property
    def id(self):
        return self.__id

    @id.setter
    def id(self, id=None):
        if isinstance(id, int):
            self.__id = id
        else:
            raise Exception('"id" must be an integer ')

    @property
    def updateable(self):
        return self.__updateable

    @updateable.setter
    def updateable(self, updateable=None):
        if isinstance(updateable, bool):
            self.__updateable = updateable
        else:
            raise Exception('"updateatable" must be a bool')

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name=None):
        if isinstance(name, str):
            self.__name = name
        else:
            raise Exception('"name" must be a string')

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, value=None):
        if isinstance(value, np.ndarray):
            self.__value = value
        else:
            raise Exception('"value" not an instance of np.ndarray')

【问题讨论】:

标签: python class variables instance decorator


【解决方案1】:

Jones & Beazley 的书 Python Cookbook, 3rd Edition 包含秘诀 9.21 避免重复属性方法,它几乎可以满足您的需要 — 我强烈建议您获取这本书(或电子书)的副本以任何有兴趣更快成为精通 Python 程序员的人,因为它包含许多这样的宝石。 (免责声明:我与出版商或作者没有任何隶属关系。)

Python 中几乎所有的东西都是一流的对象,因此可以创建一个简单地定义属性并返回它的函数。以这种方式做事将使您能够遵循DRY Principle(并编写不那么无聊的冗余代码)。

def typed_property(name, expected_type):
    storage_name = '__' + name

    @property
    def prop(self):
        return getattr(self, storage_name)

    @prop.setter
    def prop(self, value):
        if not isinstance(value, expected_type):
            type_name = expected_type.__name__
            raise TypeError('"{}" must be a {}'.format(name, type_name))
        setattr(self, storage_name, value)

    return prop


class Variable():
    __type = 'Variable'

    id = typed_property('id', int)
    updateable = typed_property('updateable', bool)
    name = typed_property('name', str)
    value = typed_property('value', np.ndarray)

    def __init__(self, id=None, updateable=True, name='Variable', value=None):
        if id is not None:
            self.id = id
        if value is not None:
            self.value = value
        self.updateable = updateable
        self.name = name

【讨论】:

  • 这正是我想要的。感谢您的帮助。
  • 在这种形式中使用“__”不会触发名称修改机制。虽然它会有效地“隐藏”存储属性名称,但实际上它会使类中的代码无法访问它——必须牢记这一点。
  • @jsbueno:是的……我只是按照 OP 的方式保留它。
猜你喜欢
  • 2021-08-20
  • 2015-04-18
  • 2021-05-15
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2016-11-20
  • 2017-07-26
相关资源
最近更新 更多