2012-02-29 8 views
3

Все, Как указано в названии, возможно ли изменить способ дескриптора __get__ во время выполнения. Я нахожусь в ситуации, когда у меня есть функция, которую украшали и декомпилировали на лету во время выполнения. Я хочу, чтобы результат этой функции был доступен как атрибут, аналогичный тому, что делает @property. Я исследовал это и нашел его дескриптором, но кажется, что метод дескрипторов __get__ доступен только для чтения.Можете ли вы изменить метод __get__ дескриптора python во время выполнения?

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

    @property 
    def x(self): 
     return self.get_x() 

Приведенный выше код делает то, что я хочу, грубо говоря, в том, что

  1. Значение задается в конструкторе
  2. можно украсить метод get_x к содержанию моего сердца
  3. instance.x возвращается правильное значение

Моя проблема в том, что я бы предпочел не иметь создайте метод get_x, поскольку он в основном не нужен. Я просто не смог украсить метод x12, как он доступен только для чтения.

фон

Я пишу стратегию игру пошаговой, и я использую декоратор реализовать постоянные условия. Я могу эффективно использовать эти декораторы, когда я использую тестовые примеры, но проблема в том, что для получения вычисленного значения вы должны использовать вызов функции, а не доступ к атрибуту. Это кажется плохой идеей, потому что получение значений, описывающих единицу, будет непоследовательно использовать функции или атрибуты. Я бы хотел стандартизировать атрибуты, если смогу.

ответ

4

Вы можете переопределить значение по умолчанию «только для чтения» характеристика __get__ атрибута property «s с помощью простого наследования:

class MyProperty(property): pass 

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

    @MyProperty 
    def x(self): 
     return self.get_x() 

test = Test() 

Проблема теперь, даже если вы переопределить __get__ attribure вашего имущества Text.x, на test.x запрос питон во время выполнения будет вызывать MyProperty.__get__(Test.x, test, Test)

Таким образом, вы могли бы переписать его только там, как

MyProperty.__get__ = lambda self,instance,owner: ""the x attribute" 

Так хороший вариант здесь делегировать вызов некоторым redifineable атрибута как

MyProperty.__get__ = lambda self,instance,owner: self.get(instance,owner) 

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

class MyProperty(property): 
    def __get__(self,instance,owner) : 
     if not instance: return self 
     else: return self.get(instance,owner) 

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

    @MyProperty 
    def x(self): pass 

    @MyProperty 
    def y(self): pass 

    x.get = lambda self,clazz: self.get_x() 
    y.get = lambda self,clazz: "the y property of " + clazz.__name__ + " object" 

>>> test = Test() 
>>> test.x 
10 
>>> test.y 
'the y property of Test object' 
+0

Спасибо, я буду смотреть в этот этот вечер, но похоже, что он делает то, что я хочу. Если все будет работать, я приму ответ. – mklauber

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

  • Нет связанных вопросов^_^