在python中声明它们的主体之前是否可以使用函数?

时间:2009-12-15 18:14:28

标签: python

有没有办法在你真正声明它们的主体之前使用你文件中的函数?

以下代码似乎不起作用:

abc = myFunction

def myFunction():
    print "123"

由于

5 个答案:

答案 0 :(得分:19)

在分配之前,您无法使用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

答案 1 :(得分:13)

您可以声明使用前向声明的函数,但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的绑定更改为函数对象。

答案 2 :(得分:1)

简短的回答是否定的。

在Python中,语句在解析时进行评估 - myFunction未被解析,因此Python不知道它。

答案 3 :(得分:1)

您可以声明一个空函数,用它来设置属性或类似的东西,然后稍后修改它的代码。

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

答案 4 :(得分:1)

Python会在遇到任何对之前没有绑定的名称(有效变量/类/函数/对象名称的标记)的任何引用时引发NameError。

Python解释器在读取文件时执行文件的源代码。因此def foo():实际上是在加载代码时定义foo()的语句。

很容易认为支持前向引用。考虑一下:

def foo():
    return abc

abc="FooBar, Dude"

print foo()

......你会发现它可以毫无问题地运行。最好将foo()的定义视为引用。在调用函数之前,不会评估内容。因此,不会引发NameError(只要在调用函数之前某些值已绑定到名称“abc”。

请注意,其中一些语义与Java,C / C ++和Perl等语言的语义完全不同,Pythonistas通常更喜欢使用稍微不同的术语。变量等被称为“名称”,并且将这些变量与值(或更一般地,对象)相关联的过程被称为“绑定”。因此,不是“为变量赋值”,而是“将对象绑定到名称。”

非正式名称,特别是对于简单的数字或字符串对象,称为“变量”,而x='foo'等语句称为赋值。语义通常相似,我们不在乎。