2013-05-07 3 views
0

Пожалуйста, не смейтесь. Я в отчаянии.Свойства с сахаром и без него

Вот канонический пример класса питона с геттер и сеттер (от Wikipedia):

class Student(object): 
    # Initializer 
    def __init__(self, name): 
     # An instance variable to hold the student's name 
     self._name = name 

    # Getter method 
    @property 
    def name(self): 
     return self._name 

    # Setter method 
    @name.setter 
    def name(self, new_name): 
     self._name = new_name 

Теперь моя версия без декораторов:

class Student(object): 
    # Initializer 
    def __init__(self, name): 
     # An instance variable to hold the student's name 
     self._name = name 

    # Getter method 
    def name(self): 
     return self._name 
    name=property(fget=name) 

    # Setter method 
    def set_name(self, new_name): 
     self._name = new_name 
    name = property(fset=set_name) 

... за исключением того, что вторая версия просто не работает. Если мы установим класс Студента, например. Bob=Student('Bob'), Bob.name выбрасывает атрибут AttributeError: нечитаемый.

Я обещаю пожертвовать 100 очков, как только моя репутация достигает 10k к доброй душе, которая наклоняется, чтобы указать на ошибку перед downvotes начать вливать

+3

Что вы хотите сказать? –

+0

Извините, вторая половина вопроса не сделала это с первой попытки. Надеюсь, теперь этот вопрос будет читабельным. –

+2

Код в виде отступов не будет работать. Пожалуйста исправьте. – chepner

ответ

4

Вы должны назвать сорбент тоже:.

name = property(fget=name, fset=set_name) 

или просто

name = property(name, set_name) 

См property documentation.

Синтаксис декоратора @ - это просто синтаксический сахар; следующий вид:

@decorator_expression 
def function_name(...): 
    ... 

выполнен в виде:

def function_name(...): 
    ... 
function_name = decorator_expression(function_name) 

Обратите внимание, как decorator_expression части рассматриваются как вызываемая с помощью функции передается в качестве первого аргумента. A property() в этом отношении не отличается.

После первого свойства определяются для name, у вас есть нового объект name в вашем пространстве имен класса, в property объекте. Этот объект имеет .setter() метод, который просто возвращает свойство с сеттерами заменен новой функцией прошла в.

Таким образом, синтаксис приводит к .setter() метода на существующем property например, называют, и что метод возвращает свойство с заменяемым устройством.

Таким образом, вы можете также по буквам вашего явного создателя собственности, таким образом:

name = property(name) 
name = name.setter(set_name) 

Ваша версия просто заменить свойство name (определяется с геттер) с одним определяющим только сеттера, то два, не имеющие никакого отношения иначе.

+1

Или, чтобы быть ближе к форме '@ name.setter',' name = name.setter (set_name) '. – delnan

+0

@ delnan: Я добирался туда. :-) –

0

геттеры и сеттеры не имеют никакого смысла в питоне, если только они на самом деле ничего не делают.

class kid: 
    def __init__(self,name): 
     self.name = name 


>>>bill = kid('bill') 
>>>bill.name = 'johnny' #is good enough 
>>>bill.name 
johnny 
>>>bill.job = 'student' 
>>>bill.job 
student 
+3

Правда, но это был не вопрос. – delnan