python:如何从其中引用类(如递归函数)

KL.*_*KL. 25 python class

对于递归函数,我们可以这样做:

def f(i):
  if i<0: return
  print i
  f(i-1)

f(10)
Run Code Online (Sandbox Code Playgroud)

但有没有办法做以下事情?

class A:
  # do something
  some_func(A)
  # ...
Run Code Online (Sandbox Code Playgroud)

小智 28

如果我正确理解您的问题,您应该能够通过将类型注释放在引号中来引用 A 类中的 A 类。这称为前向引用。

class A:
  # do something
  def some_func(self, a: 'A')
  # ...
Run Code Online (Sandbox Code Playgroud)

请参阅下面的参考

  1. https://github.com/python/mypy/issues/3661
  2. https://www.youtube.com/watch?v=AJsrxBkV3kc

  • 你所描述的内容仅对制作类型注释有用 - 很可能**不是** OP 所询问的内容...... (5认同)

Anu*_*yal 19

在Python中,你不能在类体中引用类,尽管在像Ruby这样的语言中你可以做到.

在Python中,您可以使用类装饰器,但是在类初始化后将调用它.另一种方法可能是使用元类,但这取决于你想要实现的目标.

  • 你如何使用类装饰器和元类来实现这一点?一个例子会很棒。 (5认同)
  • 为什么呢?在这方面,类定义体与函数体有何不同?鉴于函数和类都是第一类对象,因此它们主体的差异对我来说并不是立即显而易见的。编辑:正如下面的另一个答案指出的那样,函数体*不*在执行定义本身时执行,而类体作为类定义执行的一部分执行。 (2认同)

Mar*_*ddy 8

由于评估它们的时间,您无法使用您描述的特定语法.给出的示例函数的作用是在函数体内调用f(i-1)是因为在实际调用函数之前不执行f的名称解析.此时,f存在于执行范围内,因为已经评估了该函数.对于类示例,在仍在评估类定义的过程中会查找对类名的引用.因此,它在本地范围内尚不存在.

或者,可以使用类似这样的元类来完成所需的行为:

class MetaA(type):

    def __init__(cls):
        some_func(cls)

class A(object):
    __metaclass__=MetaA
  # do something
  # ...
Run Code Online (Sandbox Code Playgroud)

使用此方法,您可以在评估类时对类对象执行任意操作.

  • 这是解释“为什么”它无法完成的唯一答案(函数体不仅仅根据定义执行,而类体则执行)。感谢您的澄清。 (2认同)

car*_*arl 0

如果你想引用同一个对象,只需使用'self':

class A:
    def some_func(self):
        another_func(self)
Run Code Online (Sandbox Code Playgroud)

如果你想创建同一个类的新对象,只需这样做:

class A:
    def some_func(self):
        foo = A()
Run Code Online (Sandbox Code Playgroud)

如果您想访问元类类对象(很可能不是您想要的),请再次执行以下操作:

class A:
    def some_func(self):
        another_func(A) # note that it reads A, not A()
Run Code Online (Sandbox Code Playgroud)

  • 只是澄清一下:在最后一个示例中,引用“A”被称为“类对象”,而不是“元类”,这是一个完全不同的概念。示例中 A 的元类将是“types.ClassType”(如果使用新样式类或 python3,则为“type”) (2认同)