2015-05-12 2 views
1

В книге «Программирование ядра на Python» есть пример о том, как использовать свойство. Код выглядит так:если свойство образца работает

class Hidex(object): 
    def __init__(self, x): 
     self.__x = x 
    @property 
    def x(): 
     def fget(self): 
      return ~self.__x 
     def fset(self, x): 
      assert isinstance(val, int), 'val must be int' 
      self.__x = ~x 
     return locals() 

В книге говорится, этот класс будет работать со следующим кодом:

inst = Hidex(20) 
print inst.x 
inst.x = 30 
print inst.x 

Но я не думаю, что этот класс будет работать. потому что при доступе inst.x интерпретатор будет фактически запускать Hidex.__dict__['x'].__get__(x, Hidex), а поскольку x = свойство (x), первым аргументом arg 'fget' является x, а не функция 'fget', определенная в x().

Кроме того, когда я запускаю этот код, я получил результат:

{'fget': <function fset at 0x.....>, 'self': <__main__.xxxx>, 'fget': <function fget at 0x....>} 
traceback: 
...... # this result is just telling t.x = 30 cannot run, just skip the details 
AttributeError: cannot set attribute 

ли я что-то пропустил? почему книга предполагает, что это может работать?

+0

'этот код не работает either.' - Пожалуйста, объясните реальную проблему. Почему, по-вашему, код не работает нормально? – thefourtheye

+0

привет @ thefourtheye, я обновляю проблему. Думаете ли вы, что мы можем использовать свойство, чтобы сосать такой способ? – Spybdai

ответ

0

Это сделало бы Sence:

class Hidex(object): 

    def __init__(self, x): 
     self.__x = x 

    @property 
    def x(self): 
      return ~self.__x 

    @x.setter 
    def x(self, x): 
     assert isinstance(x, int), 'val must be int' 
     self.__x = ~x 

Выглядит как @property в коде вашего вопроса не встроенная, а другая версия.

Это, скорее всего, что было задумано здесь:

def nested_property(func): 
    """Make defining properties simpler. 
    """ 
    names = func() 
    names['doc'] = func.__doc__ 
    return property(**names) 


class Hidex(object): 
    def __init__(self, x): 
     self.__x = x 
    @nested_property 
    def x(): 
     def fget(self): 
      return ~self.__x 
     def fset(self, x): 
      assert isinstance(x, int), 'val must be int' 
      self.__x = ~x 
     return locals() 
+0

Большое спасибо, @ Майк Мюллер, я знаю, что это сработает. Мой вопрос в том, что книга настаивает на том, что приведенный выше код работает, но я так не думаю. И я не уверен, что я что-то пропущу. – Spybdai

+0

Это может быть проблема. Если это так, то похоже, что книга нуждается в обновлении – Spybdai

+0

@Spybdai Да. Была еще одна проблема с копией. Он говорит 'assert isinstance (val, int)', но он должен быть 'x' not' val'. Полагаю, есть необходимость в модульных тестах для примеров кода книги. –

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