我有一个我想要了解的Python框架.其中一个类有以下__init__()个:

def __init__(self, identity, direction, type, app_name, *aspects):

通常(为了清楚起见),我try 使用函数的关键字来调用函数,例如:

destination = RNS.Destination(
    identity=identity,
    direction=RNS.Destination.IN,
    type=RNS.Destination.SINGLE,
    app_name=APP_NAME,
    aspects='minimalsample',
    )

在如上实例化类时,我得到的异常是Destination.__init__() got an unexpected keyword argument 'aspects'.

我认为这是因为aspects参数实际上不是一个关键字参数,而是一个附加位置参数列表. 好的,所以它不是真正的Kwarg,所以我try 将‘MinimalSample’参数作为第一个参数传递:

destination = RNS.Destination(
    'minimalsample',
    identity=identity,
    direction=RNS.Destination.IN,
    type=RNS.Destination.SINGLE,
    app_name=APP_NAME,
)

但后来我得到了

TypeError:为参数‘Identity’获取了多个值

我想我看到了问题所在,但我不知道如何在保持使用关键字的清晰度的同时调用函数.有什么好办法吗?

以前可能有人问过这个问题(甚至很多次),但我似乎找不到我正在使用的搜索词的答案.

推荐答案

记录在案的 signature个 已经很清楚了.

RNS.Destination(身份、方向、类型、APP_NAME、*方面)

它需要你这样称呼它:

import RNS
from RNS.Destination import IN, SINGLE

aspects: list[str] = ['minimalsample', 'largesample']

dest = RNS.Destination(identity, IN, SINGLE, APP_NAME, *aspects)

如果aspects是一个单元素列表,那么这种方法也是一样的.

以下是1到2个方面的等同传递方式:

  • ... , APP_NAME, 'minimalsample')
  • ... , APP_NAME, 'minimalsample', 'largesample')

*args表示我们传入了一个由零个或多个参数组成的列表. 碰巧这个特定的库需要的不只是零个参数.

这一方案的作者本可以 Select 接受 aspects: list[str]分的论点, 甚至是aspects: list[str] | str, 但这并不是他们所实施的. 第一种 Select 强制调用者使用更多的[ ]括号 而不是他们对于常见的单一方面用例的偏好. 第二种 Select 是在简单的类型安全和便利性之间进行权衡 争论.


有时你会看到这样的签名:

def foo(a, b, c, d=None, e=0):

你有could个这样的电话

args = [a, b, c]
kwargs = dict(d=None, e=0)

foo(*args, **kwargs)

由于Destination接受可变数量的 方面字符串,你别无 Select ,你需要 要列出四个位置参数, 然后是一个或多个方面, 后跟zero个关键字参数, 如果希望字节码推送 把所有正确的东西放到堆栈上 到构造函数执行时.

如果你想更好地了解细节, disassemble个 一些calling函数的字节码.


当库作者设计公共API时, 强制调用者使用位置参数的方法不止一种.

https://docs.python.org/3/faq/programming.html#what-does-the-slash-in-the-parameter-list-of-a-function-mean

函数参数列表中的斜杠(/)是什么意思?

函数的参数列表中的斜杠表示其之前的参数是仅位置参数.仅位置参数是没有外部可用名称的参数.

百人组 指PEP-570, 这就解释了

在设计API时,库作者试图确保正确和预期地使用API

并继续讨论谨慎 Select 名字的问题 还有几个挑战.

一些你可能更常看到的 Signature是一颗赤裸裸的*星,这引入了 仅限关键字的参数. 例如,一位图书馆作者关心 关于(x,y)与(y,x)混淆, 源于(Late,Long)vs(Long,Lat), 可能会 Select 这样的签名:

def gis_location(*, x, y):

这可以防止try 的(不正确的!)调用,例如

lhr = gis_location(51.48, -0.46)

并且需要更明确的

lhr = gis_location(y=51.48, x=-0.46)

Python相关问答推荐

Django关于UniqueBindition的更新

在Python中使用readline函数时如何向下行

如何使用函数正确索引收件箱?

Altair -箱形图边界设置为黑色,中线设置为红色

PyQt5如何将pyuic 5生成的Python类添加到QStackedWidget中?

Pydantic:如何将对象列表表示为dict(将列表序列化为dict)

如何使用上下文管理器创建类的实例?

如何让 turtle 通过点击和拖动来绘制?

如何比较numPy数组中的两个图像以获取它们不同的像素

max_of_three使用First_select、second_select、

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

抓取rotowire MLB球员新闻并使用Python形成表格

处理(潜在)不断增长的任务队列的并行/并行方法

Python中的嵌套Ruby哈希

如何在Windows上用Python提取名称中带有逗号的文件?

可变参数数量的重载类型(args或kwargs)

Pandas - groupby字符串字段并按时间范围 Select

如何列举Pandigital Prime Set

如何在Raspberry Pi上检测USB并使用Python访问它?

在Python中使用if else或使用regex将二进制数据如111转换为001""