Python函数,它返回自己的带有参数的签名

Posted

技术标签:

【中文标题】Python函数,它返回自己的带有参数的签名【英文标题】:Python function which returns its own signature with parameters 【发布时间】:2021-05-15 06:05:48 【问题描述】:

标记为已解决,因为: 已解决的解决方案为该问题提供了一个足够好的解决方案,尽管它并不能完全解决按需动态生成函数名称的问题。

我想生成一个函数,它返回自己的签名和参数。这在 Python 中可能吗?因此,该函数由调用本身生成,并返回代表其自身名称和参数的字符串。

这是我正在寻找的一个简单示例:

class Object(object):
  #Impl here?
  pass

a = Object()
returned_string = a.foo(param1 = 1, param2 = "cheese")

print(returned_string)
#should print: a.foo(param1 = 1, param2 = "cheese")
#or     print:   foo(param1 = 1, param2 = "cheese")

重要的是,foo 是一个任意名称,不应“硬编码”而是生成。

代码应允许以下内容:

 print(a.doodle(param1 = 32)) #prints: doodle(param1 = 32)
 print(a.bar(param42 = "pi")) #prints: bar(param42 = "pi")

没有定义进一步的功能。

谢谢:)

【问题讨论】:

class Object(object) 是怎么回事?你能用一个例子详细说明吗?也许制作一个可以用 param1 和 param2 重现的类 import inspectinspect.stack()[0][3]可以得到当前函数的名字。 【参考方案1】:

这就是你想要的功能:

import inspect

class Object(object):

    def your_function(**options):
        return f"inspect.stack()[0][3](', '.join([str(key) + ' = ' + str(options[key]) for key in options.keys()]))"

如果你这样做:

a = Object()

a.your_function(abc="abc", ert=3)

它会返回:

your_function(abc = abc, ert = 3)

【讨论】:

【参考方案2】:

我假设您的意思是,一旦您创建了一个对象,该函数就能够为该对象返回它自己的输入参数。您当然可以将其修改为看起来像一个字符串,但您想要返回的是作为该对象和函数签名的输入参数foo

class Object():
    def foo(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
        return self.__dict__

a = Object()
returned_string = a.foo(param1 = 1, param2 = "cheese")

print(returned_string)
'param1': 1, 'param2': 'cheese'

将其作为字符串返回 -

import inspect

class Object():
    def foo(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
        d = self.__dict__
        f = inspect.stack()[0][3]
        return f+'('+', '.join([' = '.join([str(j) for j in i]) for i in d.items()])+')'

a = Object()
returned_string = a.foo(param1 = 1, param2 = "cheese")

print(returned_string)
foo(param1 = 1, param2 = cheese)

【讨论】:

差不多就是这样,但名称“foo”不应该是硬编码的,而是在我调用 a.some_name 时生成 @Asocia 它是硬编码的,因为函数名称是固定的(不管它叫什么)。任何调用 a.f1、a.f2、a.f3... 都应该返回正确的结果并被定义。 很像你可以添加变量,如:a.i_am_five = 5 @BarFoo,查看关于f = inspect.stack()[0][3]的部分。它没有硬编码。 f = inspect.stack()[0][3] 返回函数名称,而 self.__dict__ 提供该对象中参数的当前状态。这些足以为该对象+功能提供您想要的“签名”。 但是函数定义为foo。所以它永远是 a.foo(parameters)。【参考方案3】:

您应该能够使用**kwargs 做您想做的事。举个例子:

def my_args_are(**kwargs):
    return "my_args_are()".format(
        ", ".join("0 = 1!r".format(arg, val)
            for arg, val in kwargs.items()))

有效:

>>> my_args_are(param1 = 1, param2 = "cheese")
"my_args_are(param1 = 1, param2 = 'cheese')"

如果您不想硬编码名称,可以使用inspect

import inspect

def my_args_are(**kwargs):
    fname = inspect.currentframe().f_code.co_name
    argstr = ", ".join("0 = 1!r".format(arg, val)
                       for arg, val in kwargs.items()))
    return "()".format(fname, argstr)

【讨论】:

这几乎就是我要找的!剩下的问题是,如何生成“my_args_are”?因此,如果我调用 my_doodle(param1 = 1, param2 = "cheese") 我会得到 "my_doodle(param1 = 1, param2 = 'cheese')" @BarFoo 遥遥领先 :) 刷新答案。 我认为有一种方法可以在 deman 上创建未定义的函数(比如你可以写 a.foo = 32) 啊,这个还是需要显式定义函数my_args_are,难道我调用a.function_name的时候没有办法生成这个函数名吗? 好吧,老实说,我想我已经可以使用它了。我将稍微改变一下我的期望:) 我会将其标记为已解决。谢谢:)

以上是关于Python函数,它返回自己的带有参数的签名的主要内容,如果未能解决你的问题,请参考以下文章

返回作为参数提供的函数时保留类型签名

函数签名

带有指针参数的 C++ 函数

规范函数签名的必要性

Python函数相关

函数不匹配语言版本迁移中的参数,以及如何知道函数的签名