如何不使用`def`关键字定义一个函数?

5

可以不使用 class 关键字来定义类。
以下是一个示例:

get_i = lambda self: self.i    
get_i.__name__ = 'get_i'
get_i.__qualname__ = 'Klass2.get_i'
dct = dict(a=1, i=4, get_i=get_i)    
Klass2 = type('Klass2', (SuperK,), dct)

... 产生的最终结果与以下内容相同:

class Klass1(SuperK):
    a = 1
    i = 4
    def get_i(self):
        return self.i

我们如何为函数做类似的事情呢?也就是说,我们如何在不使用“def”或“lambda”关键字的情况下定义一个函数?如果以下两个代码片段创建了相同的foo,则“dehf”的纯Python实现可能是什么样子?
def foo(bar):
    bar += 934
    return bar

foo = dehf(blah, blah, blah, blah, [...])

1
你在类中使用了 lambda 来定义函数。你认为不使用 lambda 也能定义函数吗? - Barmar
创建一个带有 type 的类的用例相当罕见(例如元类)。但是为什么你想要创建一个没有 deflambda 的函数呢? - Chris_Rands
如果你想让你的代码难以维护,那么这可能是一个好主意。但在现实生活中,你有什么好理由想要使用定义类或函数的这种晦涩方式呢? - DisappointedByUnaccountableMod
@Chris_Rands @barny 一个用例是在运行时生成名称的函数。例如,假设我们想要在运行时创建一个名为baz的函数,但我们不知道当我们编写代码时它将被命名为baz。因此,我们不能简单地编写def baz(* args):。也许有一个装饰器,输出一个名为"pretty_<foo>"的函数,其中<foo>是传递给装饰器的函数。您可以编写func.__name__ = "pretty_" + foo.__name__,但是还有其他构建函数的用例,没有def关键字不容易处理。 - Toothpick Anemone
如果您的问题是关于动态创建函数名称,那么请问这个问题,而不是使用def,例如https://dev59.com/amYs5IYBdhLWcg3wDPmt。目前感觉像是一个XY问题。 - Chris_Rands
1个回答

6
您可以通过调用types.FunctionType构造函数来创建函数。但请注意,此构造函数未经记录并且实现特定。在CPython中,我们可以通过调用help(types.FunctionType)来确定构造函数参数:
class function(object)
 |  function(code, globals[, name[, argdefs[, closure]]])
 |  
 |  Create a function object from a code object and a dictionary.
 |  The optional name string overrides the name from the code object.
 |  The optional argdefs tuple specifies the default argument values.
 |  The optional closure tuple supplies the bindings for free variables.

要创建一个代码对象,我们可以使用 compile
code = compile('print(5)', 'foo.py', 'exec')
function = types.FunctionType(code, globals())

function()  # output: 5

1
有趣,但这不是 XY 问题吗?你为什么要这样做? - Chris_Rands
1
@Chris_Rands 没有头绪,你得问问原帖作者。也许只是简单的好奇心 :) - Aran-Fey
我有一个应用场景,有点儿。我有一个模块,在模块范围内生成一组函数。它运行良好,但是完全混淆了IDE和代码验证工具。所以我需要为每个函数添加一个存根,并且这些存根可以用类似你的例子更紧凑地表示。 - Roger Dahl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接