【问题标题】:Automatically apply getter and setter to new object variable自动将 getter 和 setter 应用于新对象变量
【发布时间】:2014-12-07 11:55:16
【问题描述】:

好的,假设我有一个非常简单的类,即:

class Test(object):
    pass

我想做的是定义一些默认的setter和getter方法 它们会在创建时自动应用于新的对象成员。在下面的示例中,a.x 应始终为大写,即:

a = Test()
a.x = "foo"
print a.x 
>>> FOO

如果我在类中创建x,我会得到这样的行为:

class Test(object):
    def __init__(self):
        self._x = ""

    @property
    def x(self):
        return self._x

    @x.setter(self, string):
        self._x = string.upper()

那么有没有可能在不为每个成员定义 setter 和 getter 方法的情况下做到这一点?非常感谢。

编辑:创建时间是指a.x 的创建时间,而不是类实例的创建时间。

【问题讨论】:

    标签: python


    【解决方案1】:

    最简单的方法可能是覆盖__setattr__,并将任何字符串值更改为大写:

    >>> class Test(object):
        def __setattr__(self, attr, val):
            if isinstance(val, basestring):
                val = val.upper()
            super(Test, self).__setattr__(attr, val)
    
    
    >>> t = Test()
    >>> t.x = 'foo'
    >>> t.x
    'FOO'
    

    【讨论】:

    • 我最初有那个,然后我想我开始想太多了:在创建时会自动应用于新的对象成员...所以我在想如果在__init__ 中初始化的类属性/或属性应免除大写字母...
    • 好吧,也许我有点不清楚,我的意思是新成员的创建时间,即'a.x'对不起。
    【解决方案2】:

    子类化一个字典;

    In [1]: %cpaste
    Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
    :class Struct(dict):
    :    """A dict subclass where you can simply use a dot to access attributes."""
    :
    :    def __getattr__(self, name):
    :        return self[name]
    :
    :    def __setattr__(self, name, value):
    :        self[name] = value
    :--
    
    In [2]: a = Struct()
    
    In [3]: a.x = "foo"
    
    In [4]: a.x
    Out[4]: 'foo'
    
    In [5]: a.length = 14
    
    In [6]: a
    Out[6]: {'length': 14, 'x': 'foo'}
    

    【讨论】:

      【解决方案3】:

      这听起来像是 python 的用例Descriptor Proctocol

      class WithDescriptors:
          x = UpperCaseDescriptor()
          y = UpperCaseDescriptor()
          z = UpperCaseDescriptor()
      
      
      class UperCaseDescriptor(object):
          def __init__(self):
              self.val = ''
      
          def __get__(self, obj, objtype):   
              return self.val.upper()
      
          def __set__(self, obj, val):
              self.val = val
      

      这只是一个大纲,我没有测试代码是否可以工作!

      如果您想将此类行为扩展到实例的每个属性, 即使不存在,你也应该考虑metaclasses

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-27
        • 2017-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多