2010-12-13 84 views
2

__getattr____setattr__当我使用点符号获取或设置对象的属性时,效果很好。 如何拦截模块内部的获取和设置模块全局变量?当访问全局变量时,模块的__setattr__和__getattr__

我子模块类型:

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()中不存在的一些变量,并且我想替换请求的值。

UPDATE:

上述代码作为我需要不工作:访问变量a不受print反射。

我正在使用PyQt4编写一个'平台',其他用户(程序员)添加窗体和模块来处理与这些窗体的交互。表单本身可通过用户模块通过'注入'变量form访问。我想让用户有可能从窗体小部件和简单的方式访问值。而不是写if form.myCheckbox.isChecked()form.myCheckbox.setChecked(myValue)我想提供一个快捷方式:if myCheckboxmyCheckbox = myValue,拦截访问值,使所需要的工作背景:

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

为什么你想这样做? – 2010-12-13 18:53:16

+0

你真正的问题是什么,因为你似乎已经回答了“我如何拦截从模块内部获取和设置模块全局变量?”? – 2010-12-13 18:54:06

回答

2

你不能。

的基本问题是,当你访问一个属性属性重载只能工作,特别是这意味着:

 
expr.ident 

没有网点,不能有任何属性超载。因此,无论你做什么,像

 
a 

的顺序永远不能调用属性过载,不管还有什么可以等同于价值a

0

你想做的事情不能在一般情况下完成。你不能有一个属性都有一个值和一个属性。您可以做form.myCheckbox = Truebool(form.myCheckbox),form.myCheckbox.setChecked(True)bool(form.myCheckbox.isChecked()),而不是两者。我的意思是,form.myCheckbox不能同时是TrueQCheckbox对象。你可以使它的工作为bool,intunicode可以处理,但不方便,而其他类型通常是不可能的。

除此之外,你对__getattr__做什么感到困惑。它不被称为存在的属性,__getattribute__是。但是使用__getattribute__很复杂,你可能想制作复选框描述符或使用属性,但是你必须放弃模块并使用类。

P.S.为什么要形成一个模块,而不是某个对象的实例?

+0

'form'是一个从.ui文件加载的QDialog。 我使用'__getattr__'截取尚未定义的属性 – warvariuc 2010-12-13 19:55:44