簡體   English   中英

在 class 實例中使用模塊變量

[英]Using a module variable within a class instance

我有一個多次實例化的 class。 它需要配置文件中的某個參數。 我想在模塊級別讀取一次配置文件,以便每個實例都可以引用加載的參數。

我可能在收到以下信息時遺漏了一些東西:
UnboundLocalError: local variable 'the_parameter' referenced before assignment

這是代碼的大綱:

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('config.cfg')
the_parameter = config.getint('my_section','the_parameter')

class MyClass():
    def my_func(self):
        print(the_parameter)

為我工作

>>> class MyClass( object ):
...     def aFunc( self ):
...         print( some_global )
... 
>>> some_global= 3
>>> x= MyClass()
>>> x.aFunc()
3

發布的代碼可能刪除了太多細節以顯示真正的錯誤。

不要試圖在你的類中使用全局變量,這有點違背類的目的。 如果您的 class 需要配置 object,您可以通過依賴注入傳遞它,即將它作為參數顯式傳遞給您的 class:

config = ConfigParser.ConfigParser()
config.read('config.cfg')

class MyClass(object):
    def __init__(self, config):
        self._config = config

    def my_func(self):
        print self._config.getint('my_section', 'the_parameter')

順便說一句,如果你真的只需要單個參數,你當然可以傳遞參數而不是整個配置 object。 如果您將來可能需要其他參數,傳遞配置 object 將是更好的選擇。

global the_parameter放入 function 以解決此問題。

S.Lott 是對的:OP 的代碼有效。
它可以與在類定義之前或之后定義的the_parameter一起使用,沒關系。

What happens is that when the function my_func is called as a method of one of the instances, the object the_parameter is searched in the environment of the my_func 's code block, that is to say: first in the local scope of the function, then在 function 之外,直到全局命名空間(= 模塊級別),因為“當在代碼塊中使用名稱時,它使用最近的封閉 scope 解析。” 參考

因此,沒有必要為不存在的問題找到解決方案。

.

但是,IMO 可以改進此代碼,因為它實際上意味着必須在全局級別綁定的所有對象中找到the_parameter ,並且這些對象可能非常多。
在函數代碼中定義global the_parameter縮短了研究過程:執行將 go 直接在全局級別搜索 object,而無需探索函數的命名空間。

但無論如何,在這兩種情況下,這是一個糟糕的過程,與類的目的相反,正如 jena 強調的那樣:一個實例必須是一個自給自足的object具有提供其功能所需的所有字段的字段。

.

jena 的解決方案還不是最好的,因為它意味着每次創建實例時都必須將 the_parameter作為參數傳遞。
如果_parameter旨在對MyClass的所有實例始終通用,則代碼應使其成為與MyClass的所有實例更嚴格關聯的 object。

所以在我看來,下面的代碼更方便:

class MyClass(object):
    import ConfigParser
    config = ConfigParser.ConfigParser()
    config.read('config.cfg')
    the_parameter = config.getint('my_section','the_parameter')
    del ConfigParser,config  

    def my_func(self):
        print('the_parameter == ' + str(MyClass.the_parameter)) 

這樣做, the_parameter的搜索將通過探索 class 的命名空間來完成,而不是在廣闊的全局命名空間中。

.

更新

好吧,我意識到要找到MyClass.the_parameter ,執行必須首先在全局命名空間中搜索 object MyClass ,這會破壞我的假裝。

為避免在全局命名空間中搜索,對實例的_class _屬性的調用必須按如下方式進行:

def my_func(self):
    print('the_parameter == ' + str(self.__class__.the_parameter)) 

如果您不將 var 聲明為全局並且不對其進行初始化,則訪問未定義變量的值是錯誤的

所以

global the_parameter = config.getint(...)

是答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM