Функции модуля с аргументами по умолчанию и пространствами имен?

#python #module #namespaces

Вопрос:

Я хочу собрать несколько общеполезных функций в модуль my_module. Эти функции должны иметь аргументы по умолчанию, которые являются переменными в рабочей области. Когда я перемещаю эти функции из основного кода в модуль, а затем импортирую их в основной код, я получаю ошибку, так как эти аргументы по умолчанию не могут быть найдены.

 y = 1;
def f(x, y=y):
   sum =  x y
   return sum

f(1)
 

И когда f вместо этого импортируется из my_module, у нас есть

 y = 1
from my_module import f

f(1)
 

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

Комментарии:

1. вам пришлось бы довольно сильно изменить функцию своего модуля, чтобы выполнить взлом. Вам нужно будет проверить файл, из которого вызывается функция, и проанализировать его глобальные переменные и т. Д. Полученный код был бы действительно уродливым и непитоническим. Я бы отклонил такой код во время проверки. Вместо этого передайте переменную функции при ее вызове.

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

Ответ №1:

my_module.py:

 y = 1

def f(x, y = None):
    if y is None:
        y = globals()['y']
    sum = x y
    return sum
 

test.py

 import my_module
my_module.y = 2
f = my_module.f
print(f(1))
 

Комментарии:

1. интересный. но это мой модуль. y = 2 не изменяет его также для всех файлов, импортирующих его ?

2. Я думаю, что ваше намерение в вашем примере состоит в том, чтобы показать, что в тесте вы импортируете my_module и меняете y с 1 на 2, а затем вводите «измененный f» с f=my_module.f. Но функция f (), которую вы сейчас используете, НЕ изменена. Он по-прежнему использует y=1, который был у него в файле определения my_module.py. Таким образом, f(1) также на этот раз равно 2. Это означает, что строка my_module.y=2 не играет никакой роли… Пространства имен-это немного сложно!

3. @janpeter ты прав, я забыл, как работают необязательные аргументы, я обновил код, и теперь он работает

4. @AnthonyPerot это повлияет на весь импорт, my_module. y-это как глобальная переменная для всего приложения

5. Что-то здесь все еще хитрое, и вскоре попробуем сформулировать это в этом примере.