我遇到一些问题。我们如何在可以在类属性中使用的函数之外定义函数?另外,如何将self
参数插入函数签名?我想像这样可视化:
>>> def a(self, x): #I thought maybe class will give "self" to this property function
... print(self)
...
>>> class aa:
... def __init__(self):
... pass
... @a
... def p():
... print('in it')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in aa
TypeError: a() missing 1 required positional argument: 'x'
我想在外部定义一个函数,但要在一个类内部使用。就像类的方法作为属性一样。我该怎么办?
答案 0 :(得分:0)
如果您想创建一个使用在类外部定义的函数的属性,则将是这样的:
def myfunc(self):
return self._p
class Foo:
def __init__(self, p):
self._p = p
p = property(myfunc)
f = Foo("Alpha")
f.p # gives "Alpha"
property
接受一个函数作为其(第一个)参数。该函数应具有self
作为参数,并应返回您希望属性评估的值。
答案 1 :(得分:0)
目前还不清楚您要让类外函数做什么。有很多可能性,但是您可能还不知道要向我们描述的术语。
这是我认为最有可能的三个:
您可能希望您的功能成为装饰器。这意味着您可以将@decorator
语法的方法应用于其他函数,包括类中的方法。
为此,需要编写函数以接受函数对象作为其唯一参数。它返回的内容将替换将被调用的函数或方法,因此通常您希望返回一个可调用对象,但是可以像property
一样返回一个描述符。尝试这样的事情:
def decorator(func):
def wrapper(self, *args, **kwargs):
print("in the wrapper")
result = func(self, *args, **kwargs)
print("wrapper is done")
return result
return wrapper
class Foo:
@decorator
def foo(self, x):
print("in foo(), x is", x)
f = Foo()
f.foo(1) # prints three messages
调用foo
方法时,实际上是要调用装饰器应用于原始方法(wrapper
)后返回的func
方法。由于我们编写包装程序的方式,它将调用func
,因此原始方法也将打印出其消息。
您可能想使用property
(描述符类型)来调用类外函数。这种使用property
的方法比在方法上将其作为装饰器使用的方法要少得多,但这并非不可能。您甚至可以具有两种不同的功能,一种是在请求属性时调用,另一种是在设置属性时调用(但我将仅使用getter进行演示):
def getter(obj):
print("in the getter")
return 1
class Foo2:
foo = property(getter)
f2 = Foo2()
print(f2.foo) # prints a message from the getter function first, then prints 1
请注意,以这种方式构建属性时,不能使用@decorator
语法。那只是函数定义之前的合法语法,我们没有在类内部定义任何函数。
您可能只想将在类外部定义的函数复制到其中,而无需任何修饰符或属性。这是最简单的操作,只是一个简单的任务:
def func(self, x):
print("x is", x)
class Foo3:
method = func # just assign the global to a name in the class body
func = func # you can even use the same name if you don't mind confusing people
f3 = Foo3()
f3.method(1)
f3.func(2)