为什么Python不允许在其定义中引用一个类? [英] Why doesn't Python allow referencing a class inside its definition?

查看:498
本文介绍了为什么Python不允许在其定义中引用一个类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python(3和2)不允许在它的正文中引用一个类(除了方法):

  A类:
static_attribute = A()

> ,因为'A'未定义,而

  class A:
def method(self):
return A('argument')

工作正常。
在其他语言中,例如Java,前者是没有问题的,它在许多情况下是有利的,例如实现单例。



为什么不可能在Python?

编辑:
我编辑了我的其他问题,所以它只要求规避这种限制的方法,而这个问题要求其动机/技术细节。

解决方案

Python是一种动态类型语言,在您导入模块时执行语句 >。没有类对象的编译定义,该对象是通过执行 class 语句创建的。



像一个函数一样执行类体,接着生成局部命名空间以形成体。因此代码如下:

  class Foo(object):
bar = baz

大致翻译为:

  def _Foo_body():
bar = baz
return locals()
Foo = type('Foo',(object,),_Foo_body())

因此,直到 class 语句完成执行。在语句完成之前,不能使用类语句中的名称,方法与在 def 语句完成定义之前不能使用函数一样



这意味着您可以动态地动态创建类:

  def class_with_base(base_class):
class Foo(base_class):
pass
return Foo

您可以将这些类存储在列表中:

  classes = [class_with_base(base)for base in list_of_bases] 

现在你有一个没有全局名称。没有全局名,我不能依赖在方法中存在的这样的名称; return Foo 将无法工作,因为没有 Foo 全局引用。



接下来,Python支持一个称为 metaclass 的概念,类似于类产生实例。上面的 type()函数是默认的元类,但是你可以自由提供一个类。元类可以自由地生成任何它喜欢真的,甚至是位类的东西!像这样的Python不能,前面,知道什么样的对象一个语句将产生,不能假定它会结束绑定的名称使用。请参见 Python中的元类是什么?



所有这些都不是你可以用Java这样的静态类型语言做的。


Python (3 and 2) doesn't allow you to reference a class inside its body (except in methods):

class A:
    static_attribute = A()

This raises a NameError in the second line because 'A' is not defined, while this

class A:
    def method(self):
        return A('argument')

works fine. In other languages, for example Java, the former is no problem and it is advantageous in many situations, like implementing singletons.

Why isn't this possible in Python? What are the reasons for this decision?

EDIT: I edited my other question so it asks only for ways to "circumvent" this restriction, while this questions asks for its motivation / technical details.

解决方案

Python is a dynamically typed language, and executes statements as you import the module. There is no compiled definition of a class object, the object is created by executing the class statement.

Python essentially executes the class body like a function, taking the resulting local namespace to form the body. Thus the following code:

class Foo(object):
    bar = baz

translates roughly to:

def _Foo_body():
    bar = baz
    return locals()
Foo = type('Foo', (object,), _Foo_body())

As a result, the name for the class is not assigned to until the class statement has completed executing. You can't use the name inside the class statement until that statement has completed, in the same way that you can't use a function until the def statement has completed defining it.

This does mean you can dynamically create classes on the fly:

def class_with_base(base_class):
    class Foo(base_class):
        pass
    return Foo

You can store those classes in a list:

classes = [class_with_base(base) for base in list_of_bases]

Now you have a list of classes with no global names referring to them anywhere. Without a global name, I can't rely on such a name existing in a method either; return Foo won't work as there is no Foo global for that to refer to.

Next, Python supports a concept called a metaclass, which produces classes just like a class produces instances. The type() function above is the default metaclass, but you are free to supply your own for a class. A metaclass is free to produce whatever it likes really, even things that are bit classes! As such Python cannot, up front, know what kind of object a class statement will produce and can't make assumptions about what it'll end up binding the name used to. See What is a metaclass in Python?

All this is not something you can do in a statically typed language like Java.

这篇关于为什么Python不允许在其定义中引用一个类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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