2014-12-07 57 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