почему чтение из переменной среды в аргументе метода не дает значения None или значения по умолчанию в python. Переменная среды устанавливается перед вызовом

#python #python-3.x #environment-variables

#python #python-3.x #переменные среды

Вопрос:

** Хотя имя задано в переменной среды, оно выводит значение по умолчанию **

 import os

def test(name: str = os.environ.get('name_config', "dns")):

    print("function env is:", os.getenv('name_config'))
    print("name is ::", name)

if __name__ == "__main__":

    os.environ['name_config']= "john"
    print("env is:", os.getenv('name_config'))
    #print(os.environ)
    test()
    test("test-name")
  

~
~

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

1. Каков ожидаемый результат для вашего кода?

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

3. @JoshKarpel я ожидаю вывода как «john», т.е. «имя:» john

Ответ №1:

Результаты, которые я получаю, имеют смысл:

 env is: john
function env is: john
name is :: dns
function env is: john
name is :: test-name
  

Первая строка печатается:

 print("env is:", os.getenv('name_config'))
  

Это имеет смысл, потому что вы просто установили для нее значение ‘john’ в предыдущей строке.

Вторая строка печатается:

     print("function env is:", os.getenv('name_config'))
  

Также имеет смысл по той же причине — это все еще то значение, поскольку оно вызывается позже, а переменная среды не изменяется.

Третья строка печатается:

     print("name is ::", name)
  

При этом выводится значение name , которое является параметром функции, которая была вызвана как:

     test()
  

Поскольку вы не указали значение, name будет иметь значение по умолчанию, которое задается как:

 def test(name: str = os.environ.get('name_config', "dns")):
  

Итак, это было бы os.environ.get('name_config', "dns") во время определения функции. Это было до того, как вы изменили его на ‘john’, и, по-видимому, name_config переменной не было, поэтому вместо этого вы получаете значение по умолчанию.

Это, вероятно, основное, что вас смущает, и, как и другие, ключевым моментом является то, что значения в def операторе вычисляются при def первом выполнении (т. Е. Определяется Функция), а не при вызове функции.

Четвертая строка печатается:

     print("function env is:", os.getenv('name_config'))
  

После второго вызова этой функции:

     test("test-name")
  

Поскольку вы просто снова получаете переменную среды, на данный момент она по-прежнему «john».

Наконец, пятая строка печатается:

     print("name is ::", name)
  

Это часть того же вызова, но поскольку вы теперь указали явное значение для name , а именно 'test-name' , которое печатается.

Итак, все имеет смысл?

Ответ №2:

Значение по умолчанию для аргумента вычисляется при определении функции. Поскольку os.environ['name_config']= "john" не вычисляется до тех пор, пока def test(name: str = os.environ.get('name_config', "dns")): не будет выполнено, и заблокировано в значении до вашего изменения, эффект от него не виден. Если вы хотите, чтобы это сработало, отложите разрешение значения по умолчанию до фактического запуска функции, например:

 def test(name: str = ""):  # "" is just an arbitrary string value we assume the user wouldn't use
    if not name:
        name = os.environ.get('name_config', 'dns')
    print("function env is:", os.getenv('name_config'))
    print("name is ::", name)