Как в python задать глобальную переменную в функции не используя global

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

Вот условный пример моего кода:

a = ''

def func():
    a = input()
    if not a:
        print('a is empty')
    else:
        print('a is not empty')

func()

Этот код условно должен проверять a - это пустая переменная или нет.

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


Ответы (6 шт):

Автор решения: dtroyan

Лучше передать функции эту переменную, провести с ней какие-то действия, и вернуть результат функции через 'return', и переписать переменную.

→ Ссылка
Автор решения: S. Nick

Как вариант:

def func(a):
#    a = input()
    if not a:
        print('\na is empty')
        a = f'a is empty --> `{a}`'
    else:
        print('\na is not empty')
        a = f'a is not empty --> `{a}`'
    return a

a = ''        
a = func(a)
print(f'1. a = {a}')

a = 'Hello'        
a = func(a)
print(f'2. a = {a}')
→ Ссылка
Автор решения: passant

Глобальные переменные плохи не от того, что они задаются описателем global. Они плохи потому, что неявное описание переменных усложняет логику программ, ее читаемость, отлаживаемость и предсказуемость результатов. Вы их или используете (и неважно как ) или нет. А если используете - то точно понимая все риски и точно понимая, зачем вы на них идете. И ответив (хотя-бы себе) на вопрос - а без них можно?

А если делать все "как положено" - то просто передаете переменную в функцию явно, а в функции выполняете свои проверки и модификации. Только и всего - просто и понятно.

→ Ссылка
Автор решения: IPOleksenko

Вынеси переменную за блок функций

a = 1
b = 2
def ab():
    print(a + b)

вывод: 3

→ Ссылка
Автор решения: CrazyElf

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

Вот в этом случае можно завести, например, специальный класс, который хранит эти параметры, а все ваши функции берут параметры из полей этого класса. А сам этот класс может загружать параметры из файла, например. Класс этот можно вынести в отдельный файл и импортировать этот файл когда нужны эти параметры.

Хотя по сути класс - это тоже в общем-то глобальная переменная, но класс - это лучше, чем переменная, переменные обычно называют абы как, а у класса скорее всего будет выделенное "говорящее" название и в одном классе будет собрано много параметров, а не так, что много глобальных переменных непонятно откуда взявшихся, ищи потом, откуда они, как и чего.

Ещё в случае, если вам нужно менять какие-то переменные в нескольких функциях, удобно вынести эти переменные в какой-то класс опять же, а функции сделать методами этого класса. Тогда эти функции-методы будут иметь прямой доступ к этим переменным-полям, при этом они не будут засорять этими переменными глобальное пространство имён и мешать другим функциям/классам. Чем и хороша собственно инкапсуляция - один из трёх принципов, на которых стоит ООП.

→ Ссылка
Автор решения: Blazzerrr

Как самый простой и самый понятный вариант

def func():
    a = input()
    if not a:
        print('a is empty')
        return ''

    else:
        print('a is not empty')
        return a

a = func()
→ Ссылка