获取Python中内置函数的参数(arg)数量

2023-12-15

我为 Python 和文档中的自定义表编写了自己的 c 模块我需要运行时内置函数的参数数量.

Python 2 中有类似的函数检查.getargspec或 Python 3 中的函数,例如检查签名它支持普通的 Python 函数,但不支持内置函数。

目前还有另外两个社区解决方案:

  • 解析文档字符串
  • 解析原始*.c文件
  • 请参阅第三种方法的答案

在某些情况下,文档字符串已经过时和/或很难提取参数计数,因为文档字符串可以是任何纯字符串。解析原始 *.c 文件也是一个好方法,但您可能无权访问它。


下面这就是working我为 Python 2 和 3 提出的解决方案。

它有什么作用?

在运行时,99 个 None 对象的列表被传递给相应的函数。内部解析函数中的第一个检查PyArg_ParseTuple检查参数的数量是否与传递的参数的数量匹配 - 如果不匹配,则会失败。这意味着我们将调用该函数,但我们也可以确定它不会真正执行。

技术背景:

为什么获取内置函数的参数个数这么难?问题在于参数列表是在运行时而不是编译时评估的。 C 中内置函数的一个非常简单的示例如下所示:

static PyObject* example(PyObject *self, PyObject *args)
{
    int myFirstParam;
    if(!PyArg_ParseTuple(args, "i", &myFirstParam))
        return NULL;
    ...
}

复制粘贴解决方案:

import inspect
import time
import re
import types
import sys


def get_parameter_count(func):
    """Count parameter of a function.

    Supports Python functions (and built-in functions).
    If a function takes *args, then -1 is returned

    Example:
        import os
        arg = get_parameter_count(os.chdir)
        print(arg)  # Output: 1

    -- For C devs:
    In CPython, some built-in functions defined in C provide
    no metadata about their arguments. That's why we pass a
    list with 999 None objects (randomly choosen) to it and
    expect the underlying PyArg_ParseTuple fails with a
    corresponding error message.
    """

    # If the function is a builtin function we use our
    # approach. If it's an ordinary Python function we
    # fallback by using the the built-in extraction
    # functions (see else case), otherwise
    if isinstance(func, types.BuiltinFunctionType):
        try:
            arg_test = 999
            s = [None] * arg_test
            func(*s)
        except TypeError as e:
            message = str(e)
            found = re.match(
                r"[\w]+\(\) takes ([0-9]{1,3}) positional argument[s]* but " +
                str(arg_test) + " were given", message)
            if found:
                return int(found.group(1))

            if "takes no arguments" in message:
                return 0
            elif "takes at most" in message:
                found = re.match(
                    r"[\w]+\(\) takes at most ([0-9]{1,3}).+", message)
                if found:
                    return int(found.group(1))
            elif "takes exactly" in message:
                # string can contain 'takes 1' or 'takes one',
                # depending on the Python version
                found = re.match(
                    r"[\w]+\(\) takes exactly ([0-9]{1,3}|[\w]+).+", message)
                if found:
                    return 1 if found.group(1) == "one" \
                            else int(found.group(1))
        return -1  # *args
    else:
        try:
            if (sys.version_info > (3, 0)):
                argspec = inspect.getfullargspec(func)
            else:
                argspec = inspect.getargspec(func)
        except:
            raise TypeError("unable to determine parameter count")

        return -1 if argspec.varargs else len(argspec.args)



def print_get_parameter_count(mod):
    for x in dir(mod):
        e = mod.__dict__.get(x)
        if isinstance(e, types.BuiltinFunctionType):
            print("{}.{} takes {} argument(s)".format(mod.__name__, e.__name__, get_parameter_count(e)))

import os
print_get_parameter_count(os)

Output:

os._exit takes 1 argument(s)
os.abort takes 0 argument(s)
os.access takes 2 argument(s)
os.chdir takes 1 argument(s)
os.chmod takes 2 argument(s)
os.close takes 1 argument(s)
...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取Python中内置函数的参数(arg)数量 的相关文章

随机推荐

  • 我的代码的 Boost 更新问题

    我最近将 boost 更新到 1 59 并安装在 usr local 中 我的系统默认安装在 usr 并且是1 46 我使用的是ubuntu 12 04 我的代码库使用 ROS Hydro 机器人操作系统 我有一个相当大的代码库 在更新之前
  • 是(n+1)!按照 (n!) 的顺序?你能给我一个证明吗?

    那 n 1 呢 另外 如果你能给我一个证明 可以帮助我更好地理解 我被困在这一点上 证明 n 1 在 O n 中 你必须证明存在一个常数 c 以便对于所有足够大的 n n gt n0 不等式 n 1 lt c n 成立 然而 由于 n 1
  • 使用 jquery 将下拉菜单链接到锚文本

    我在我的页面上选择下拉菜单
  • 未找到名为 os 的模块 - Django、mod_wsgi、Apache 2.2

    我正在尝试设置 apache mod wsgi 和 django 我的 apache 错误日志中出现了内部服务器错误 Wed Jun 22 21 31 55 2011 error client 1 mod wsgi pid 2893 Tar
  • 将 Json 文件内容保存到 python/pandas 中的 CSV 文件

    如何将 数据 信息放入最后所示的 csv 表中 以及正确的 标头 以便源服务器不会让我以为我正在抓取数据 到目前为止我写的代码如下 import requests json headers User Agent Mozilla 5 0 da
  • 令人困惑的宏和枚举定义

    我正在浏览一些 Route netlink 源代码 我想弄清楚 RTNLGRP NEIGH 的值是多少 Source http lxr free electrons com source include linux rtnetlink h
  • 使用 OpenGLES 抗锯齿去除绳索的锯齿状边缘

    我已经实现了绳索 其中我使用 Revolute 关节连接动态 b2bodied 现在我成功创建了这条绳索 但我的绳索看起来不光滑 我希望它们像丝带一样光滑 任何对此有想法的人 我发现它可以通过 openGLES 使用抗锯齿来实现 但仍然不知
  • PHP SimpleXML 大文件没有额外的内存使用

    在每一篇有关 SimpleXML 性能和内存使用的文章中 都会提到所有解析的内容都存储在内存中 处理大文件将导致大量的内存使用 但最近我发现使用 SimpleXML 处理大文件不会导致大量内存使用 甚至几乎不会导致内存使用 有我的测试脚本
  • 删除 Azure 资源组中年龄超过 x 天的所有资源

    我尝试在资源组 python api 中的资源上 扩展 creationTime 这样我就可以找到它的年龄 如果 gt max age days 我就会删除资源组中的资源 但creationTime似乎在资源上不可用 是否有另一种方法可以根
  • 用多种颜色为轴刻度文本着色

    我正在尝试绘制一个heatmap using R s plotly包 我希望为 y 轴刻度文本的特定标签设置特定的颜色 这是一个示例数据集 set seed 1 df lt reshape2 melt matrix rnorm 100 10
  • ASIO 示例代码在应该之前关闭套接字

    我需要一个使用 ASIO 的并行同步 TCP 解决方案 我正在尝试从这些示例中获取示例代码 https github com jvillasante asio network programming cookbook tree master
  • Java 中的检查异常与非检查异常

    我在理解之间的差异时遇到一些问题checked and uncheckedJava 中的异常 首先 checked异常应该在编译时查找异常 不同来源提供的示例引用了数据库连接 文件处理等其中一些 而unchecked异常应该查找程序员的错误
  • 如何在非 UWP C# 项目中访问 Windows.Gaming.Input?

    我见过一些在 C 控制台应用程序中使用 Windows Gaming Input 的示例 但是否也可以在非 UWP C 项目中访问它 Thanks 我已经通过执行以下操作成功做到了这一点 确保 VisualStudio 未运行 打开你的项目
  • Magento - 显示产品所属的类别

    我使用下面的代码在我的产品页面上显示产品所属的类别 但我经营相同产品的多商店 它还显示其他网站的类别 如何只显示我正在访问的网站的类别 a href a
  • Jquery load() 一个包含 JavaScript 的 html 文件

    我有一个很大的困境 我想加载一个 html文件包含 javascript google 地图 代码来渲染其中的 div maps html 看起来像这样
  • Rails Postgres 查询,仅选择出现在所有搜索参数中且具有关联的项目

    我正在寻找基于一些用户选择参数创建一个 Postgres 查询 用户将选择商店以及开始和结束年份 提交后 我只想显示仅存在于所选所有年份的商品的平均价格 例如 用户选择开始日期为 2014 年 结束日期为 2018 年 项目香蕉在所有这些年
  • 在Java中缩短字符串

    我需要将 ABC123 等 6 个字符的字符串缩短为唯一的 4 个字符的字符串 它必须是可重复的 以便输入字符串始终生成相同的输出字符串 有谁有任何理想如何做到这一点 不可能执行从 6 个字符的字符串到 4 个字符的字符串的完全唯一的映射
  • 如何在 C 中以十六进制字节格式打印浮点数?

    我想查看 IEEE754 格式表示形式的浮点值 3 14159265 于是写了这段测试代码 include
  • 计算给定日期范围内星期一的数量

    给定一个日期范围 我需要知道该范围内有多少个星期一 或星期二 星期三等 我目前正在使用 C 工作 尝试这个 static int CountDays DayOfWeek day DateTime start DateTime end Tim
  • 获取Python中内置函数的参数(arg)数量

    我为 Python 和文档中的自定义表编写了自己的 c 模块我需要运行时内置函数的参数数量 Python 2 中有类似的函数检查 getargspec或 Python 3 中的函数 例如检查签名它支持普通的 Python 函数 但不支持内置