2014-12-07 2 views
1

Ok, позволяет сказать, что у меня есть очень простой класс, а именно:Автоматически применять методы получения и установки для нового переменного объекта

class Test(object): 
    pass 

То, что я хотел бы сделать, это определить некоторые по умолчанию сеттера и методы получения , которые автоматически применяется к новому объекту во время создания. В приведенном ниже примере топор всегда должен быть в верхнем регистре, то есть:

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() 

Так есть ли возможность сделать это без определение методов сеттера и геттера для каждого члена? Спасибо большое.

EDIT: С созданием времени я имел в виду время создания 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__' должен быть освобожден от верхней части корпуса ... –

+0

Ну, может быть, я был немного неясен, я имел в виду время создания нового члена, то есть «топор». Мне жаль. – jrsm

+0

@jonrsharpe: Спасибо за хороший ответ. – jrsm

1

Подкласс a dict;

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

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.

Смежные вопросы