Ошибка в подпрограмме Excel для импорта текстового файла с фиксированной шириной с не-ASCII-символами

Не было никакого тщательного ответа относительно времени Python3, поэтому я сделал здесь ответ.

Как указано в других ответах, есть четыре основных области, LEGB, для Local, Enclosing, Global и Builtin. В дополнение к этим, существует особая область, тело класса, которая не содержит охватывающей области для методов, определенных внутри класса; любые присваивания внутри тела класса делают переменную оттуда связанной с телом в классе.

В частности, никакой блок-оператор, кроме def и class, не создает область переменной. В Python 2 понимание списка не создает область переменной, однако в Python 3 переменная цикла создается в новой области.

Чтобы продемонстрировать особенности тела класса

x = 0
class X(object):
    y = x
    x = x + 1 # x is now a variable 
    z = x

    def method(self):
        print(self.x) # -> 1
        print(x)      # -> 0, the global x
        print(y)      # -> NameError: global name 'y' is not defined

inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)

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


. Одна из больших неожиданностей для многих новичков на Python заключается в том, что цикл for не создает область переменной. В Python 2 представления в списках не создают области (как в случае генераторов, так и в выражениях dict)! Вместо этого они пропускают значение в функции или глобальной области:

>>> [ i for i in range(5) ]
>>> i
4

. Понимание может быть использовано как коварный (или ужасный, если хотите) способ сделать изменяемые переменные в лямбда-выражениях в Python 2 - выражение лямбда создает переменную область видимости, как и оператор def, но в пределах лямбда никаких утверждений не допускается. Назначение, являющееся выражением в Python, означает, что никакие назначения переменных в лямбда не разрешены, но понимание списка является выражением ...

Это поведение было исправлено в Python 3 - нет выражений понимания или переменных утечки генераторов.


Глобальное действительно означает область модуля; основным модулем python является __main__; все импортированные модули доступны через переменную sys.modules; для доступа к __main__ можно использовать sys.modules['__main__'] или import __main__; вполне приемлемо для доступа и назначения атрибутов; они будут отображаться как переменные в глобальной области основного модуля.


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

x = 5
def foobar():
    print(x)  # causes UnboundLocalError!
    x += 1    # because assignment here makes x a local variable within the function

# call the function
foobar()

scope может объявить, что он явно хочет изменить глобальную (область видимости модуля) с глобальным ключевым словом:

x = 5
def foobar():
    global x
    print(x) # -> 5
    x += 1

foobar()
print(x) # -> 6

Это также возможно, даже если оно было затенено в охватывающей области:

x = 5
y = 13
def make_closure():
    x = 42
    y = 911
    def func():
        global x # sees the global value
        print(x, y)
        x += 1

    return func

func = make_closure()
func()      # -> print 5 911
print(x, y) # -> 6 13

В python 2 нет простого способа изменить значение в охватывающей области; обычно это моделируется с помощью изменяемого значения, такого как список с длиной 1:

def make_closure():
    value = [0]
    def get_next_value():
        value[0] += 1
        return value[0]

    return get_next_value

get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2

Однако в python 3 nonlocal приходит на помощь:

def make_closure():
    value = 0
    def get_next_value():
        nonlocal value
        value += 1
        return value
    return get_next_value

get_next = make_closure() # identical behavior to the previous example.
< hr>

Любая переменная, которая не считается локальной для текущей области или любой охватывающей области, является глобальной переменной. Глобальное имя просматривается в глобальном словаре модуля; если он не найден, глобальный отображается с модуля встроенных модулей; имя модуля было изменено с python 2 на python 3; в python 2 это было __builtin__, а в python 3 теперь называется builtins. Если вы назначаете атрибут встроенного модуля, после этого он будет отображаться в любом модуле как читаемая глобальная переменная, если только этот модуль не тени их собственной глобальной переменной с тем же именем.


Чтение встроенный модуль также может быть полезен; предположим, что вы хотите использовать функцию печати в стиле python 3 в некоторых частях файла, но в других частях файла по-прежнему используется оператор print, если ваша версия python равна> = 2.6, вы можете получить новую функцию стиля как:

import __builtin__

print3 = __builtin__.__dict__['print']

На самом деле from __future__ import print_function не импортирует функцию print в любом месте Python 2, вместо этого он просто отключает правила синтаксического анализа для оператора print в текущем модуле, обрабатывая print, как и любую другую переменную Идентификатор и, таким образом, позволяет print искать функцию во встроенных функциях.

0
задан Kerry Jackson 21 March 2019 в 22:46
поделиться