__Setattr__ и __getattr__ модуля при доступе к глобальным переменным - PullRequest
2 голосов
/ 13 декабря 2010

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

I Тип модуля подкласса:

from types import ModuleType
class WUserModule(ModuleType):
    def __init__(self, name):
        super().__init__(name)

    def __setattr__(self, name, value):
        if name in self.__dict__:
             super().__setattr__(name, value)
             return
        print('Set name {}, value {}'.format(name, str(value)))

    def __getattr__(self, name):
        print('Get name {}'.format(name))

Создать пустой модуль и загрузить в него код:

module = WUserModule('form_module')
with open('user_module.py', 'r', encoding='utf8') as f:
    exec(f.read(), module.__dict__)

Код, загруженный из user_module.py:

a=1
print(a)

Мне нужно как-то перехватить доступ к переменной a.В загруженном коде ожидается доступ к некоторым переменным, которых нет в модуле globals(), и я хочу заменить запрошенные значения.

ОБНОВЛЕНИЕ:

Приведенный выше код не работает, как япотребность: доступ к переменной a не отражается print.

Я использую PyQt4 для написания «платформы», где другие пользователи (программисты) добавляют формы и модули, которые обрабатывают взаимодействие с этими формами.Сама форма доступна в пользовательском модуле через введенную переменную form.Я хочу предоставить пользователям возможность доступа к значениям из виджетов форм и более простой способ.Вместо того, чтобы писать if form.myCheckbox.isChecked() или form.myCheckbox.setChecked(myValue), я хочу предоставить ярлык: if myCheckbox и myCheckbox = myValue, перехватывая доступ к значениям и заставляя необходимую работу в фоновом режиме:

def __getattr__(self, name):
    formWidget = getatttr(form, name)
    if isinstance(formWidget, QLineEdit):
        formWidget.setText(value)
...

Ответы [ 2 ]

2 голосов
/ 13 декабря 2010

Вы не можете.

Основная проблема заключается в том, что перегрузки атрибута работают только при обращении к атрибуту, в частности это означает:

<em>expr</em> <b>.</b> <em>ident</em>

Без точки не может быть перегрузки атрибута. Таким образом, независимо от того, что вы делаете, последовательность, как

<b>a</b>

Никогда не может вызвать перегрузку атрибута, независимо от того, что еще может равняться значению из a.

0 голосов
/ 13 декабря 2010

То, что вы пытаетесь сделать, не может быть сделано в общем случае. Вы не можете иметь атрибут, оба имеют значение и атрибут. Вы можете сделать form.myCheckbox = True и bool(form.myCheckbox), или form.myCheckbox.setChecked(True) и bool(form.myCheckbox.isChecked()), , а не оба. Я имею в виду, что form.myCheckbox не может быть True и QCheckbox объектом одновременно. Вы могли бы заставить это работать для bool, int и unicode, могут быть обработаны, но неудобно, в то время как другие типы вообще невозможны.

Кроме этого, вы не понимаете, что делает __getattr__. Он не вызывается для атрибутов, которые существуют, __getattribute__ есть. Но использование __getattribute__ сложно, вы можете захотеть сделать дескрипторы своих флажков или использовать свойства, но тогда вам придется отказаться от модулей и использовать классы.

P.S. Почему формируется модуль, а не экземпляр какого-либо объекта?

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