2010-12-13 72 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