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

Можно ли использовать функции перед объявлением своего тела в python?

Есть ли способ сделать возможным использовать функции в вашем файле, прежде чем вы на самом деле объявите свое тело?

Следующий код не работает:

abc = myFunction

def myFunction():
    print "123"

Спасибо

4b9b3361

Ответ 1

Вы не можете использовать переменную myFunction до ее назначения. Ваш примерный код похож на:

def myFunction():
    print abc
    abc = 123

Чтобы сделать то, что вы хотите, переустановите заказ:

def myFunction():
    print "123"

abc = myFunction

Или объявите abc как просто прокси:

# Style 1
abc = lambda: myFunction()

# Style 2
def abc():
    return myFunction()

def myFunction():
    print "123"

Если ваша функция принимает параметры, используйте *args и **kwargs:

# Style 1
abc = lambda *args, **kwargs: myFunction(*args, **kwargs)

# Style 2
def abc(*args, **kwargs):
    return myFunction(*args, **kwargs)

def myFunction(x):
    print x

Ответ 2

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

def foo():
    print "in foo"
    bar()

def bar():
    print "in bar"
    foo()

foo()

(за исключением того, что, конечно, это приведет к переполнению стека во время выполнения). В вашем примере Python выполняет строку

abc = myFunction

до myFunction определяется как что-либо. Вы могли бы подумать об этом с точки зрения ввода вашего исходного кода в интерактивном режиме в интерпретаторе. Когда вы вводите свое задание, вы даже не ввели бы определение myFunction, поэтому Python не смог бы ссылаться на него.

Другой способ взглянуть на это может быть следующим:

>>> myFunction = "hello"
>>> abc = myFunction
>>> def myFunction():
...     print "there"
... 
>>> abc
'hello'
>>> myFunction
<function myFunction at 0x63270>
>>> myFunction()
there

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

Ответ 3

короткий ответ - нет.

В Python операторы оцениваются по мере их анализа - myFunction не анализировался, поэтому Python не знает об этом.

Ответ 4

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

def myFunction():
    pass

myFunction.foo = 'bar'

def makeFunction(obj):
    def myFunction():
        print "123"

    f = myFunction
    for attr in dir(obj):
        if attr not in dir(f):
            setattr(f, attr, getattr(obj, attr))

    return f


myFunction = makeFunction(myFunction)
myFunction()
print myFunction.foo

Ответ 5

Python поднимет значение NameError, поскольку он встретит любую ссылку на любое имя (токен, который имеет действительную переменную/класс/функцию/имя объекта), для которого ранее не было привязки.

Интерпретатор Python выполняет исходный код файла по мере его чтения. Таким образом, def foo(): - это оператор, который определяет foo() при загрузке кода.

Легко думать, что поддерживаются прямые ссылки. Рассмотрим это:

def foo():
    return abc

abc="FooBar, Dude"

print foo()

... и вы увидите, что он может запускаться без проблем. Лучше всего думать о определении foo() как о цитировании. Содержимое не оценивается до тех пор, пока функция не будет вызвана. Таким образом, NameError не создается (пока какое-то значение привязано к имени "abc" перед вызовом функции.

Обратите внимание, что некоторые из этих семантик достаточно различны, чем некоторые из таких языков, как Java, C/С++ и Perl, которые Pythonistas часто предпочитают использовать немного другую терминологию. Переменные и такие называются "именами", а процесс объединения значений со значениями (или, в более общем смысле, объектов) называется "привязкой". Поэтому вместо "присвоения значений переменным" вы "привязываете объекты к именам".

Неформальные имена, особенно для простых числовых или строковых объектов, называются "переменными", а такие выражения, как x='foo', называются назначениями. Семантика обычно достаточно схожа, что нам все равно.