应该在python中使用之前定义函数吗?

时间:2013-09-13 20:39:21

标签: python function

应该在使用之前定义函数吗?但为什么以下代码有效:

def main():
    dog()

def dog():
    print("This is a dog.")

if __name__ == '__main__':
    main()

我的意思是dog()是在调用之后定义的,它是如何工作的?

3 个答案:

答案 0 :(得分:7)

实际上它不是(在被称之后定义)。该脚本将执行以下操作:

  • 创建功能并将其分配给“main”
  • 创建功能并将其分配给“dog”
  • 致电“main”

此时dog已在全球范围内公开,main可以调用它。

答案 1 :(得分:6)

名称dog被查找为全局名称。对全局变量的引用在实际使用之前不需要引用任何定义的内容。函数main()在调用之前不会使用dog

如果未定义dog,则调用main()会导致NameError例外:

>>> def main():
...     return dog()
... 
>>> main()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in main
NameError: global name 'dog' is not defined
>>> def dog():
...     return 'Woof!'
... 
>>> main()
'Woof!'

Python并不关心dog 的内容。我也可以把它变成一个类,或者甚至是不可调用的东西:

>>> class dog:
...     pass
... 
>>> main()
<__main__.dog instance at 0x10f7d3488>
>>> dog = 'Some string'
>>> main()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in main
TypeError: 'str' object is not callable

因为在最后一个示例中,dog现在绑定到字符串,所以main函数在尝试调用时失败。

答案 2 :(得分:2)

在调用函数之前,函数/方法块中的代码不会执行。 CPython语言实现(这是最常见的一个和你可能正在使用的实现)在编译时不会像C这样的语言进行名称检查。因为它主要是一种解释语言,它会检查名称是否可用于命名空间在运行时动态。

此外,您应该了解Python的一点是类中的代码是在创建类时执行的,但是在方法/函数中的代码不是。 def语句只是将函数的名称添加到命名空间。在调用函数之前,它不会在函数内运行任何代码。

考虑以下合法的Python代码。

class Something:
    def __init__(self):
        self.puppy = Dog()

class Dog:
    def __init__(self):
        pass

inst = Something()

这是完全合法的,因为在__init__类定义之前未运行Dog。但是,如果我们将该构造函数移到创建类Dog之上呢?

此代码会抱怨NameError,因为Dog尚未定义!

class Something:
    def __init__(self):
        self.puppy = Dog()

inst = Something()

class Dog:
    def __init__(self):
        pass

最后一个例子......

此代码会抱怨同样的NameError。

class Something:
    my_puppy = Dog()
    def __init__(self):
        self.puppy = Dog()

class Dog:
    def __init__(self):
        pass

inst = Something()

这是因为Something内的所有代码都被立即执行,并且在执行的那一刻,命名空间/范围无法访问名称Dog

相关问题