Использование переменной модуля в экземпляре класса - PullRequest
1 голос
/ 12 июля 2011

У меня есть класс, который создается много раз.Требуется определенный параметр из файла конфигурации.Я думал о том, чтобы прочесть файл конфигурации один раз на уровне модуля, чтобы каждый экземпляр мог ссылаться на загруженный параметр.

Возможно, я что-то упускаю при получении:
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)

Ответы [ 5 ]

4 голосов
/ 12 июля 2011

Работает для меня

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

В опубликованном коде, вероятно, было удалено слишком много деталей, чтобы показать реальную ошибку.

3 голосов
/ 12 июля 2011

Не пытайтесь использовать глобальные переменные в ваших классах, это несколько противоречит назначению классов. Если вашему классу требуется объект конфигурации, вы можете передать его через внедрение зависимостей, то есть явно передать его в качестве аргумента вашему классу:

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')

Кстати, если вам действительно нужен только один параметр, вы, конечно, можете передать параметр вместо всего объекта конфигурации. Если в будущем вам могут понадобиться другие параметры, лучше всего передать объект конфигурации.

1 голос
/ 26 августа 2011

S.Lott прав: код OP работает.
Он работает либо с the_parameter , определенным до определения класса, либо после, это не имеет значения.

Что происходит, когда функция my_func вызывается как метод одного из экземпляров, объект the_parameter ищется в среде Блок кода my_func , то есть: сначала в локальной области функции, затем за пределами функции, до глобального пространства имен (= уровень модуля), потому что "Когда имя используется вблок кода, он разрешается с использованием ближайшей охватывающей области. " ( ref )

Таким образом, нет необходимости искать решение проблемы, которой не существует.

.

Однако этот код может быть улучшен IMO, поскольку он подразумевает, что the_parameter должен быть найден среди всех объектов, связанных на глобальном уровне, иэти объекты, возможно, очень многочисленны.
Определение global the_parameter внутри кода функции сокращает процесс исследования: выполнение будет идти непосредственно на глобальном уровне для поиска объекта, без исследования пространства имен функцииТуз.

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

.

Решение jena еще не является лучшим, поскольку оно подразумевает, что the_parameter должен передаваться в качестве аргумента каждый раз при создании экземпляра.
Если the_parameter должен быть неизменно общим для всех экземпляров MyClass , код должен сделать егоболее строго связанный объект со всеми экземплярами MyClass .

Так что мне кажется, что следующий код более удобен:

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 будет выполняться путем исследования пространства имен класса, а не в обширном глобальном пространстве имен.

.

Обновление

Ну, японять, что найти MyClassпараметр , выполнение должно сначала найти объект MyClass в глобальном пространстве имен, и это уничтожает то, что я притворился.

Чтобы избежать поиска в глобальном пространстве имен, вызов _ class _ атрибут экземпляра должен быть выполнен так:

def my_func(self):
    print('the_parameter == ' + str(self.__class__.the_parameter)) 
1 голос
/ 12 июля 2011

Поместите global the_parameter в функцию, чтобы исправить проблему.

0 голосов
/ 12 июля 2011

Если вы не объявляете var глобальным и не инициализируете его, доступ к значению неопределенной переменной будет ошибкой

так

global the_parameter = config.getint(...)

ответ

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