Подтвердить что ты не робот

Как создать новые области действия в python

На многих языках (и в местах) существует хорошая практика создания локальных областей, создавая такой блок, как this.

void foo()
{
     ... Do some stuff ...

     if(TRUE)
     {
         char a;
         int b;

         ... Do some more stuff ...
     }

     ... Do even more stuff ...
 }

Как я могу реализовать это в python без получения неожиданной ошибки отступа и без использования если True: трюки

4b9b3361

Ответ 1

В Python область охвата имеет три типа: глобальный, локальный и класс. Вы можете создать специализированные словари "scope", чтобы перейти к exec/eval(). Кроме того, вы можете использовать вложенные области  (определение функции внутри другой). Я нашел их достаточно во всем моем коде.

Как уже сказал Дуглас Ледер, основная причина использовать его на других языках - это переменная область видимости, и на самом деле это не происходит на Python. Кроме того, Python - самый читаемый язык, который я когда-либо использовал. Это противоречило бы читаемости, чтобы сделать что-то вроде if-true трюков (о которых вы говорите, чего хотите избежать). В этом случае я считаю, что лучше всего реорганизовать ваш код на несколько функций или использовать одну область. Я думаю, что доступных областей на Python достаточно, чтобы охватить каждую возможную ситуацию, поэтому локальная область не должна быть действительно необходимой.

Надеюсь, это поможет.

Ответ 2

Почему вы все равно хотите создавать новые области в python?

Нормальная причина для этого в других языках - это изменение переменных, но это не происходит в python.

if True:
    a = 10

print a

Ответ 3

переменные в понимании списка (Python 3+) и генераторы локальны:

>>> i = 0
>>> [i+1 for i in range(10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> i
0

но зачем именно вам это нужно?

Ответ 4

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

def foo():
  a = 1

  def bar():
    b = 2
    print a, b #will print "1 2"

  bar()

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

Ответ 5

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

Ответ 6

Если вы просто хотите создать временные переменные и позволить им собирать мусор сразу после их использования, вы можете использовать

del varname

когда вы больше не хотите их.

Если это справедливо для эстетики, вы можете использовать комментарии или дополнительные строки перевода, без дополнительных отступов.

Ответ 7

Сфера - текстовая область Python, где пространство имен напрямую доступный. "Непосредственно доступный" означает, что безоговорочная ссылка на имя попытки найти имя в Пространство имен...

Пожалуйста, прочитайте документацию и уточните свой вопрос.

btw, вам не нужно if(TRUE){} в C, достаточно простого {}.

Ответ 8

def a():
    def b():
        pass
    b()

Если мне просто нужен дополнительный отступ или отладка, я буду использовать if True:

Ответ 9

Как упоминалось в других ответах, в Python нет аналогичной функциональности для создания новой области видимости с блоком, но при написании скрипта или блокнота Jupyter я часто (ab) использую классы для введения новых пространств имен для аналогичного эффекта. Например, в записной книжке, где у вас могут быть модель "Foo", "Bar" и т.д. И связанные переменные, вы можете захотеть создать новую область видимости, чтобы избежать повторного использования имен, таких как

model = FooModel()
optimizer = FooOptimizer()
...
model = BarModel()
optimizer = BarOptimizer()

или суффиксные имена вроде

model_foo = ...
optimizer_foo = ...

model_bar = ...
optimizer_bar= ...

Вместо этого вы можете вводить новые пространства имен с помощью

class Foo:
    model = ...
    optimizer = ...
    loss = ....

class Bar:
    model = ...
    optimizer = ...
    loss = ...

а затем получить доступ к переменным как

Foo.model
Bar.optimizer
...

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

Ответ 10

Обновление

Этот ответ неверен. Оператор with не ограничивает область действия; он позволяет очищать только при выходе из области действия (хотя вы можете сделать исключение исключения объекта после обращения к нему после выхода).


В зависимости от вашего случая вы можете захотеть with statement:

with Cat() as cat, Cake() as cake:
    cat.eat(cake)

эквивалентно

# scope begin
cat = Cat()
cake = Cake()
cat.eat(cake)
# scope end