Python:名称解析;函数def的顺序 [英] Python: Name resolution; order of function def's

查看:114
本文介绍了Python:名称解析;函数def的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的例子:

$ $ p $ $ $ $ $ $#$ / $ / $ / $ / $ py

#a()#1:NameError:未定义名称'a'
#b()#1:NameError:名称'b'未定义
#c()#1:NameError:名称'c'没有被定义

def a():
c()#注意这里的转发使用...

#a()#2: NameError:未定义全局名称'c'
#b()#2:NameError:名称'b'未定义
#c()#2:NameError:名称'c'未定义
$ b $ def b():
a()

#a()#3:NameError:全局名称'c'未定义
#b ()#3:NameError:全局名称'c'未定义
#c()#3:NameError:名称'c'未定义

def c():
传递

a()#这些都工作正常...
b()
c()

我有3个函数,分别为 a() b()和按照字母顺序在Python源文件中定义的 c()。每个函数定义的主体是对其他函数之一的调用。你可以通过我的评论看到,我必须首先调用这些函数的第一个函数(在文本文件中),但是你不一定需要在调用它的另一个函数上定义函数。

当然,在第一个可执行代码下面的所有函数定义(在Python和许多其他语言中)似乎是常见的做法,现在我明白了原因。在C和C ++中,头文件负责处理这个问题。在Pascal中,您必须先使用名称定义。



例如,假设您在Python中拥有此名称:

  def a(a_arg):c(a_arg)
def b(b_arg):a()
def c(a_arg,b_arg):b b_arg)
a(1)

使用 TypeError :c()在运行时只需要2个参数(1给定),其他错误是编译时间。 (在C中,这会编译,然后神秘地失败......)

在Perl中,由于子例程名称在运行时被USUALLY解析,因此可以使用Perl定义和代码任何订单:

 #!/ usr / bin / env perl 

a();
b();
c();

sub a {c(); }
sub b {a(); }
sub c {return;在C中,它要么是一个错误要么是一个警告(依赖于实现)来使用一个函数没有原型,不应该被忽略。



你可以这样做:

  void a(void){c(); } / *隐式地假定为int c(...),除非原型* / 
void b(void){a(); }
void c(void){return; }

int main(void){
a();
返回EXIT_SUCCESS;
}

我的假设和困惑是:如果Python直到运行时才解析子例程名称,为什么源代码编译阶段失败,并且尚未定义子程序名称的前向声明?它是否记录在某处(通过观察其他代码除外),您不能在源文件中的代码上面定义子例程?

看起来Python的元素包含动态名称解析(在 a()中使用 c()源文件)和静态名称解析元素(如果放在源文件定义之上,则Python无法运行对 a()>的调用)。



是否有Python版本的本文档涵盖了Perl可执行文件的生命周期以及在源文件解释和运行时间之间如何解析名称

是否存在明确的描述指定函数的Python脚本的定义顺序可以具有其他子例程名称的前向定义,但主代码不能?

编辑和结论

经过一番激烈的评论,部分,我的结论是,我的问题更多的是关于如何解析名称以及如何在Python中定义名称空间,范围和模块。

From carot-top


必须在当前名称空间中调用它之前定义一个可调用对象。
此范围和名称的链接


From S.Lott


当在代码块中使用名称时,会使用最近的附上范围。
这个链接到Python脚本的执行生命周期。


在Python文档中:


A范围定义块中名称的可见性。从 Python执行模型



模块可以包含可执行语句以及函数定义。在关于模块的更多信息



实际上,函数定义也是'语句',它们是'执行'的;模块级函数的执行在模块的全局符号表中输入函数名。在脚注里面。


我自己实现(Duh!):

每个Python源文件被Python视为一个模块:模块是一个包含Python定义和语句的文件。 $ b

  • 与Perl(我有更多经验)不同,Python在读取模块时执行模块。因此,即时可执行语句引用尚未在同一模块中定义的函数的失败。

  • 定义的顺序很简单,所有事情都必须在定义之前你称它为。这几乎就是它。



    编辑(在评论中包含答案,阐明):

    原因如下:

      def call_a():
    a()

    def a():
    pass

    call_a()

    a call_a()中有 a() c $ c>甚至被定义为一个函数,因为Python实际上只在需要的基础上查找符号的值。当计算 call_a 时, a()调用基本上被存储为字节码指令,以查找 a 是,并在到达时调用它< ,直到实际调用 call_a() 在底部。



    这是 call_a 的反汇编字节码看起来像通过 dis.dis ):
    $ b $ pre $ 反汇编call_a:
    2 0 LOAD_GLOBAL 0(a)
    3 CALL_FUNCTION 0
    6 POP_TOP
    7 LOAD_CONST 0(无)
    10 RETURN_VALUE

    所以基本上,当你点击 call_a 时,它会将任何以 a 存储的内容加载到堆栈上,将其称为函数,然后在返回 None ,w之前弹出返回值( call_a()是None 返回 True )隐含地发生了什么, p>

    I have a very simple example:

    #!/usr/bin/env python
    
    #a()  # 1: NameError: name 'a' is not defined
    #b()  # 1: NameError: name 'b' is not defined
    #c()  # 1: NameError: name 'c' is not defined
    
    def a():
        c()   # note the forward use here...
    
    #a()  #2: NameError: global name 'c' is not defined 
    #b()  #2: NameError: name 'b' is not defined
    #c()  #2: NameError: name 'c' is not defined
    
    def b():
        a()
    
    #a()   #3: NameError: global name 'c' is not defined    
    #b()   #3: NameError: global name 'c' is not defined
    #c()   #3: NameError: name 'c' is not defined
    
    def c():
        pass
    
    a()    # these all work OK...   
    b()
    c()
    

    I have 3 functions named a(), b() and c() defined in a Python source file in alphabetical order. The body of each function definition is a call to one of the other functions. You can see by my comments that I have to have the initial call to the first of these functions BELOW their definitions (in the text file), but you do not necessarily need definition of a function above another function that calls it.

    Certainly it seems to be common practice to have the first executable code below all the function definitions (in Python and many other languages), and now I can see why. In C and C++, header files take care of this. In Pascal you must have name definitions prior to their use.

    Assume, for example, that you have this in Python:

    def a(a_arg):          c(a_arg)
    def b(b_arg):          a()
    def c(a_arg,b_arg):    b(b_arg)
    a(1)
    

    It will fail properly with TypeError: c() takes exactly 2 arguments (1 given) at runtime where the other errors are compile time. (in C, this would compile then fail mysteriously...)

    In Perl, since subroutines names are USUALLY resolved at run time, you can have Perl definitions and code in any order:

    #!/usr/bin/env perl
    
    a();
    b();
    c();
    
    sub a{ c(); }
    sub b{ a(); }
    sub c{ return; }
    

    In C, it is either an error or a warning (implementation dependent) to use a function that has not been prototyped and shouldn't be ignored.

    You can have this:

    void a(void) { c(); }   /* implicitly assumed to be int c(...) unless prototyped */
    void b(void) { a(); }
    void c(void) { return; }
    
    int main(void) {
        a();
        return EXIT_SUCCESS;
    }
    

    My assumptions and confusion is this: If Python does not resolve subroutines names until runtime, why does the source compile phase fail with the forward declaration of subroutine names that have not been defined yet? Is it documented somewhere (other than by observation of other code) that you cannot have code in a source file above definitions of subroutines?

    It seems that Python has elements of dynamic name resolution (the use of c() in a() prior to its definition below in the source file) and elements of static name resolution (the failure of Python to run the call to a() if placed above its definition in the source file.)

    Is there a Python version of THIS DOCUMENT that covers the lifecycle of a Perl executable and how names are resolved between source file interpretation and runtime?

    Is there a definitive description somewhere on the order of definitions for a Python script that states functions can have forward definitions of other subroutine names but main code cannot?

    Edit and conclusion

    After some spirited comments, and some research on my part, I have concluded that my question is really more about how names are resolved, and how namespaces, scopes and modules are defined in Python.

    From carot-top:

    "a callable must be defined before it is called in the current namespace." and this link on scopes and names

    From S.Lott:

    "When a name is used in a code block, it is resolved using the nearest enclosing scope." and this link to the execution life of a Python script.

    From the Python documents:

    "A scope defines the visibility of a name within a block." From the Python Execution model

    "A module can contain executable statements as well as function definitions." in more about modules

    "In fact function definitions are also ‘statements’ that are ‘executed’; the execution of a module-level function enters the function name in the module’s global symbol table." in the footnote thereto.

    And my own realization (Duh!) that:

    1. Every Python source file is treated as a "module" by Python: "A module is a file containing Python definitions and statements."

    2. Unlike Perl (which I have more experience with) Python executes modules as they are being read. Hence the failure of a immediately executable statement referring to a function not yet defined in the same module.

    解决方案

    The order of definitions is simply "everything has to be defined before you call it". That's pretty much it.

    edit (to include answer in comments, elucidated):

    The reason something like

    def call_a():
        a()
    
    def a():
        pass
    
    call_a()
    

    works when you've got a() in call_a() before a is even defined as a function is because Python only actually looks up values for symbols on an as-needed basis. When call_a is evaluated, the a() call is basically stored as bytecode instructions to "look up what a is and call it" when the time comes, which isn't until you get down to the actual invocation of call_a() at the bottom.

    Here is what the disassembled bytecode of call_a looks like (via dis.dis):

    Disassembly of call_a:
      2           0 LOAD_GLOBAL              0 (a)
                  3 CALL_FUNCTION            0
                  6 POP_TOP
                  7 LOAD_CONST               0 (None)
                 10 RETURN_VALUE
    

    So basically, when you hit call_a, it loads whatever is stored as a onto the stack, calls it as a function, and then pops the return value off before returning None, which is what implicitly happens for anything that doesn't explicitly return (call_a() is None returns True)

    这篇关于Python:名称解析;函数def的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆