python递归函数代码_python:如何从类内部引用类(如递归函数)

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

1

2

3

4

5

6def f(i):

if i<0: return

print i

f(i-1)

f(10)

然而,有办法做下面的事情吗?

1

2

3

4class A:

# do something

some_func(A)

# ...

不清楚自己想要什么或想表达什么意思。class A:没有创建对象,因此没有可以引用的A。看看你可能想说的事情的解决方案。

创建一个类对象,因为python中的类是第一个类

在Python中,您不能在类体中引用类,但在Ruby之类的语言中,您可以这样做。

相反,在Python中,您可以使用类装饰器,但是一旦类初始化,就会调用它。另一种方法是使用元类,但这取决于您想要实现的目标。

为什么不过?在这方面,类定义体与函数体的区别是什么?由于函数和类都是第一类对象,所以它们在主体上的区别对我来说不是很明显。编辑:下面的另一个答案指出,函数体不是在定义本身被执行时执行的,而类体是作为类定义执行的一部分执行的。

如何使用类装饰器和元类来实现这一点?举个例子就好了。

您无法使用所描述的特定语法,这是由于它们被计算的时间不同造成的。给出的示例函数能够工作的原因是,在函数体中调用f(i-1)是因为直到实际调用函数时才执行f的名称解析。此时f存在于执行范围内,因为函数已经被求值了。在类示例的情况下,在仍然计算类定义的过程中查找对类名的引用。因此,它还不存在于本地范围中。

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

1

2

3

4

5

6

7

8

9class MetaA(type):

def __init__(cls):

some_func(cls)

class A(object):

__metaclass__=MetaA

# do something

# ...

使用这种方法,您可以在计算类时对类对象执行任意操作。

这是解释为什么不能执行它的唯一答案(函数体不只是根据定义执行,而类体是根据定义执行的)。谢谢你的澄清。

如果你想引用相同的对象,只需使用"self":

1

2

3class A:

def some_func(self):

another_func(self)

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

1

2

3class A:

def some_func(self):

foo = A()

如果您想访问元类类对象(很可能不是您想要的),同样,只需执行以下操作:

1

2

3class A:

def some_func(self):

another_func(A) # note that it reads A, not A()

澄清一下:在上一个示例中,引用"a"被称为"类对象",而不是"元类",这是一个完全不同的概念。在您的示例中,A的元类应该是types.ClassType(如果使用新样式的类或python3,则是type)

如果你只是想做一件不寻常的事,那就去做

1

2

3class A(object):

...

some_func(A)

如果您想做更复杂的事情,可以使用元类。元类负责在类对象完全创建之前操作它。模板应该是:

1

2

3

4

5

6

7

8

9class AType(type):

def __new__(meta, name, bases, dct):

cls = super(AType, meta).__new__(meta, name, bases, dct)

some_func(cls)

return cls

class A(object):

__metaclass__ = AType

...

type是默认的元类。元类的实例是类,因此__new__返回(在本例中)A的修改实例。

有关元类的更多信息,请参见http://docs.python.org/reference/datamodel.html#定制类创建。

不。它在函数中工作,因为函数内容是在调用时执行的。但是类内容是在定义时间执行的,此时类还不存在。

这通常不是一个问题,因为你可以在定义了类之后再入侵更多的成员,所以你可以把一个类定义分成多个部分:

1

2

3

4

5

6

7

8

9

10class A(object):

spam= 1

some_func(A)

A.eggs= 2

def _A_scramble(self):

self.spam=self.eggs= 0

A.scramble= _A_scramble

然而,在类的定义中间调用函数是非常不寻常的。不清楚您想要做什么,但是很可能您最好使用decorator(或者相对较新的类decorator)。

在类范围内没有办法做到这一点,除非首先将a定义为其他东西(然后some_func(a)将执行与预期完全不同的操作)

除非您正在进行某种堆栈检查以向类添加位,否则您为什么要这样做似乎有些奇怪。为什么不直接:

1

2

3

4

5class A:

# do something

pass

some_func(A)

也就是说,在创建完成后,在A上运行some_func。另外,如果想以某种方式修改类a,可以使用类修饰器(在2.6中添加了它的语法)或元类。你能阐明你的用例吗?

如果目标是用类作为参数调用函数some_func,那么一种方法是将some_func声明为类装饰器。注意,类装饰器是在类初始化之后调用的。它将传递作为参数修饰的类。

1

2

3

4

5

6

7

8def some_func(cls):

# Do something

print(f"The answer is {cls.x}")

return cls # Don't forget to return the class

@some_func

class A:

x = 1

如果你想传递额外的参数给some_func,你必须从装饰器返回一个函数:

1

2

3

4

5

6

7

8

9def some_other_func(prefix, suffix):

def inner(cls):

print(f"{prefix} {cls.__name__} {suffix}")

return cls

return inner

@some_other_func("Hello"," and goodbye!")

class B:

x = 2

类修饰符可以被组合,这导致调用它们的顺序与声明它们的顺序相反:

1

2

3

4@some_func

@some_other_func("Hello","and goodbye!")

class C:

x = 42

其结果是:

1

2# Hello C and goodbye!

# The answer is 42

如果类实际上在作用域中,那么可以在类的主体中引用类的名称(就像在方法定义中一样)。如果是在顶层定义的。(在其他情况下可能不会,因为Python的作用域的怪癖!)

要说明作用域的问题,请尝试实例化Foo:

1

2

3

4

5

6

7class Foo(object):

class Bar(object):

def __init__(self):

self.baz = Bar.baz

baz = 15

def __init__(self):

self.bar = Foo.Bar()

(它会抱怨没有定义全局名称"Bar"。)

另外,有件事告诉我,您可能想研究类方法:关于classmethod函数的docs(用作装饰器),这是一个相关的SO问题。编辑:好的,所以这个建议可能根本不合适……我在阅读你的问题时首先想到的是替代构造函数等。如果有一些更简单的东西适合你的需要,那就避开奇怪的东西。:-)

你想达到什么目标?可以使用元类访问类来调整其定义,但不建议这样做。

你的代码样本可以简单地写成:

1

2

3class A(object):

pass

some_func(A)

类中的大多数代码都在方法定义中,在这种情况下,您可以简单地使用名称A。

-1他问得非常具体,关于在类的主体中调用A,而不是从它的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值