Заставить импортированный метод использовать локальные переменные

1

У меня есть модуль "b", импортирующий метод из модуля "a", где метод "a.method" использует переменную, определенную в "a", должен быть переопределен в "b". просто в кодах:

module a.py:

local_var = 1
def method():
    print local_var

module b.py:

from a import method
local_var = 2
print method()

запуск python b.py prints 1, а не 2. В моем сценарии импортированный метод - это метод django, поэтому я не могу изменить модуль, и я не хочу скопировать метод в свой модуль и изменить его.

Как я могу переопределить локальную переменную другого модуля и использовать импортированный метод для новой переменной?

  • 0
    Спасибо за ответы. Я пытался добавить поддержку шаблонов jinja2 в django без особых хлопот, хотя в итоге получилось скопировать некоторые коды django для переопределения локальных переменных. Окончательная работа на github.com/altunyurt/djtemps
Теги:
scope
module
import

2 ответа

1
Лучший ответ

Попробуйте встроенную функцию exec:

Во всех случаях, если необязательные части опущены, код выполняется в текущей области. Если указано только первое выражение после in, это должен быть словарь, который будет использоваться как для глобальных, так и для локальных переменных. Если даны два выражения, они используются для глобальных и локальных переменных, соответственно. Если предоставлено, локальные жители могут быть любым объектом сопоставления.

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

Рабочий код:

a.py:

local_var = 1
def method():
    print local_var

b.py:

from a import method
import inspect

code = inspect.getsource(method)
local_var = 2
method()
print code
exec code
method()

python b.py:

vic@ubuntu:~/Desktop$ python b.py
1
def method():
    print local_var

2
vic@ubuntu:~/Desktop$ 
  • 0
    спасибо, хотя я несколько раз использовал «exec expr в globals ()», до сих пор не знал, что это такое :)
1

Вы не можете. Это по дизайну. Каждый модуль имеет собственное пространство имен.

Однако вы можете сохранить текущее значение var, присвоить новое значение, вызвать метод и восстановить исходное значение.

# module a.py:

local_var = 1
def method():
    print local_var

# module b.py:

import a
old_local_var = a.local_var
a.local_var = 2
print method()
a.local_var = old_local_var

Как отметил в комментарии джейор, этот метод следует использовать с осторожностью. Это больше или меньше рубить. Единственное допустимое использование для этого, о котором я могу думать, - это тестирование или последнее средство, когда все остальное (включая Чака Норриса) потерпело неудачу.

  • 3
    Вы правы, но OP должен быть осторожен с этим методом, особенно если он использует его на сервере с несколькими подключениями (он упомянул django). Если несколько потоков записывают в одну и ту же глобализованную переменную, результаты записи данных могут быть непредсказуемыми. Я настоятельно рекомендую не использовать этот шаблон в этой ситуации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню