gpt4 book ai didi

python - python中的函数可以表现得像一个类吗?

转载 作者:行者123 更新时间:2023-12-04 14:42:31 26 4
gpt4 key购买 nike

在 python 中,函数是第一类对象。可以调用一个类。所以你可以用一个类替换一个函数。但是你能让一个函数表现得像一个类吗?你可以在函数中添加和删除属性或调用内部函数(然后调用方法)吗?

我通过代码检查找到了一种方法。

import inspect

class AddOne(object):
"""class definition"""
def __init__(self, num):
self.num = num

def getResult(self):
"""
class method
"""
def addOneFunc(num):
"inner function"
return num + 1

return addOneFunc(self.num);

if __name__ == '__main__':
two = AddOne(1);
two_src = '\n'.join([line[4:] for line in inspect.getsource(AddOne.getResult).split('\n')])
one_src = '\n'.join([line[4:] for line in two_src.split('\n')
if line[:4] == ' ' and line[4:8] == ' ' or line[4:8] == 'def '])
one_co = compile(one_src, '<string>', 'exec')
exec one_co
print addOneFunc(5)
print addOneFunc.__doc__

但是有没有办法以更直接的方式访问类中定义的局部变量和函数?

编辑

问题是关于如何访问python的内部结构以获得更好的理解。当然,我不会在正常编程中这样做。当我们讨论 python 中的私有(private)变量时,问题就出现了。我的观点是这违背了语言的哲学。所以有人想出了上面的例子。目前看来,他是对的。如果没有检查模块,您将无法访问函数内部的函数,从而将该函数呈现为私有(private)。使用 co_varnames 我们非常接近,因为我们已经有了函数的名称。但是保存名称的命名空间字典在哪里。如果你尝试使用

getResult.__dict__

它是空的。我喜欢的是像python这样的答案

function addOneFunc at <0xXXXXXXXXX>

最佳答案

您可以将函数视为仅实现 __call__ 的类的实例,即

def foo(bar):
return bar

大致相当于

class Foo(object):

def __call__(self, bar):
return bar

foo = Foo()

函数实例有一个__dict__属性,所以你可以自由地给它们添加新的属性。


可以使用向函数添加属性,例如,实现一个 memoization 装饰器,它缓存以前对函数的调用:

def memo(f):
@functools.wraps(f)
def func(*args):
if args not in func.cache: # access attribute
func.cache[args] = f(*args)
return func.cache[args]
func.cache = {} # add attribute
return func

请注意,该属性也可以在函数内部访问,尽管直到函数之后才能定义它。


因此,您可以执行以下操作:

>>> def foo(baz):
def multiply(x, n):
return x * n
return multiply(foo.bar(baz), foo.n)

>>> def bar(baz):
return baz

>>> foo.bar = bar
>>> foo.n = 2
>>> foo('baz')
'bazbaz'
>>> foo.bar = len
>>> foo('baz')
6

(尽管可能没人会感谢你!)

但是请注意,multiply 不是 foo 的属性,不能从函数外部访问:

>>> foo.multiply(1, 2)

Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
foo.multiply(1, 2)
AttributeError: 'function' object has no attribute 'multiply'

另一个问题正是解决了您正在尝试做的事情:

>>> import inspect
>>> import new
>>> class AddOne(object):
"""Class definition."""

def __init__(self, num):
self.num = num

def getResult(self):
"""Class method."""
def addOneFunc(num):
"inner function"
return num + 1
return addOneFunc(self.num)

>>> two = AddOne(1)
>>> for c in two.getResult.func_code.co_consts:
if inspect.iscode(c):
print new.function(c, globals())


<function addOneFunc at 0x0321E930>

关于python - python中的函数可以表现得像一个类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25156374/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com