Свойства стиля C # в Python - PullRequest
0 голосов
/ 15 мая 2010

Я ищу способ определения свойств в Python, подобных C #, с вложенными определениями get / set.
Вот как далеко я добрался:

#### definition ####    

def Prop(fcn):
    f = fcn()
    return property(f['get'], f['set'])


#### test ####

class Example(object):

    @Prop
    def myattr():

        def get(self):
            return self._value

        def set(self, value):
            self._value = value

        return locals()  #  <- how to get rid of this?

e = Example()
e.myattr = 'somevalue' 
print e.myattr


Проблема в том, что ему все еще нужно определение «return locals ()».
Есть ли способ избавиться от этого?
Может быть с вложенным декоратором?

1 Ответ

2 голосов
/ 15 мая 2010

Вы можете return get, set (гораздо более элегантный подход) и превратить ваш Prop в

def Prop(fcn):
    g, s = fcn()
    return property(g, s)

Однако нет clean способа не требовать любого return оператора в декорированной функции. Функция с внутренними операторами def, так же как и с внутренними присваиваниями, на самом деле не выполняет этих операторов до тех пор, пока не будет вызвана - объекты и имена, указанные присваивания и def s, должны быть созданы и Связи буквально нигде нет.

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

Проблема заключается в том, что вы хотите декорировать объект function (который по своему замыслу хранит свои локальные имена при себе). Все было бы хорошо, если бы вы согласились использовать правильное ключевое слово вместо def для украшенной вещицы - это правильное ключевое слово class. (Обратите внимание, для этой цели вам нужен Python 2.6 или выше) ...:

def Prop(cls):
    f = cls.__dict__
    return property(f['get'], f['set'])


#### test ####

class Example(object):

    @Prop
    class myattr():

        def get(self):
            print 'getting', self._value
            return self._value

        def set(self, value):
            print 'setting', value
            self._value = value


e = Example()
e.myattr = 'somevalue' 
print e.myattr

Классы гораздо менее скрытны, чем функции, которые находятся внутри них, поэтому декоратор class может легко выполнить то, что вам нужно. Обратите внимание на крошечные изменения: __dict__ для доступа к указанию декорируемого класса, s/def/class/ в декорируемом объекте и удаление оператора return, который вам не нравится.

...