2014-12-07 58 views
1

好了,可以说我有一个非常简单的类,即:自动应用getter和setter新的对象变量

class Test(object): 
    pass 

我想什么做的是定义一些默认的setter和getter方法 这是自动在创建时应用于新对象成员。在下面斧头的例子应该始终是大写,即:

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而不是类实例。

回答

2

最简单的方法可能是覆盖__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' 
+0

我原来是这么认为的,那么我想我开始认为它是:*它们在创建时自动应用到一个新的对象成员* ...所以我想如果在'__init__'中初始化了一个类属性/或属性应该豁免上层框... – 2014-12-07 12:23:46

+0

嗯,也许我有点不清楚,我的意思是新成员的创建时间,即'斧头'我很抱歉。 – jrsm 2014-12-07 12:26:04

+0

@jonrsharpe:谢谢你的回答。 – jrsm 2014-12-07 12:27:36

1

子类字典;

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'} 
+0

也是一个很好的答案,Thx。 – jrsm 2014-12-07 12:30:39

1

这听起来像一个用例的蟒蛇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