Дескрипторы в глобальном масштабе? - PullRequest
2 голосов
/ 23 августа 2010

Протокол дескриптора в Python 2.6 определен только для определений классов и, следовательно, может использоваться только экземплярами.

Есть ли какой-нибудь эквивалент для инструментов получения / набора глобальных переменных?

Я пытаюсь ускорить импорт модуля, который взаимодействует с хост-системой, и поэтому должен выполнить некоторое дорогостоящее исследование хоста. Результаты (дорогой) проверки сохраняются в глобальном модуле, который инициализируется во время импорта; поэтому я пытаюсь отложить инициализацию до тех пор, пока это не станет абсолютно необходимым.

Пожалуйста, не комментируйте, что глобалы - это зло. Я знаю, что они есть и когда их использовать.

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

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

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

Это именно то, что я бы сделал.Нет эквивалента дескрипторам вне классов.

Другой вариант, который я также иногда использовал, заключался в использовании функции вместо имени переменной, что-то вроде этого:1009 * Если у вас уже есть определенный декоратор @memoize, вы можете значительно упростить вышесказанное.

1 голос
/ 01 июля 2014

Если вы действительно хотите это сделать, эта ссылка дает довольно крутой способ реализации.Единственное предостережение: вы должны выполнить свой код, используя eval / exec / execfile.

https://mail.python.org/pipermail/python-ideas/2011-March/009657.html

class MyDict:
    def __init__(self, mapping):
        self.mapping = mapping
    def __getitem__(self, key):
        value = self.mapping[key]
        if hasattr(value, '__get__'):
            print('Invoking descriptor on', key)
            return value.__get__(key)
        print('Getting', key)
        return value
    def __setitem__(self, key, value):
        self.mapping[key] = value

class Property:
    def __init__(self, getter):
        self.getter = getter
    def __get__(self, key):
        return self.getter(key)

if __name__ == '__main__':   
    md = MyDict({})
    md['x'] = 10
    md['_y'] = 20
    md['y'] = Property(lambda key: md['_'+key])
    print(eval('x+y+1', {}, md))

Хотя это было немного громоздко, я подумал, что это очень круто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...