Python 3.x 在python中,哪个对象确切地支持位置参数(或键区参数)的星号(或双星号)?有什么标准吗?
我使用了Python 3.x 在python中,哪个对象确切地支持位置参数(或键区参数)的星号(或双星号)?有什么标准吗?,python-3.x,asterisk,Python 3.x,Asterisk,我使用了*或**向Python2中的函数传递参数,这是毫无疑问的,通常与list、set和dictionary一起使用 def func(a, b, c): pass l = ['a', 'b', 'c'] func(*l) d = {'a': 'a', 'b': 'b', 'c': 'c'} func(**d) 但是,在Python3中,出现了新的对象,用或其他东西替换list,例如,dict\u键,dict\u值,范围,映射等等 虽然我已经将我的Python2代码迁移到Pytho
*
或**
向Python2
中的函数传递参数,这是毫无疑问的,通常与list
、set
和dictionary
一起使用
def func(a, b, c):
pass
l = ['a', 'b', 'c']
func(*l)
d = {'a': 'a', 'b': 'b', 'c': 'c'}
func(**d)
但是,在Python3
中,出现了新的对象,用或其他东西替换list
,例如,dict\u键
,dict\u值
,范围
,映射
等等
虽然我已经将我的Python2
代码迁移到Python3
,但我需要确定新对象是否能够支持Python2
中以前的对象所支持的操作,如果不能,我应该使用like类型转换将代码更改为origin类型,例如list(dict_key)
,或者其他什么
d = {'a': 'a', 'b': 'b'}
print(list(d.keys())[0]) # type-case to use list-index
对于迭代,我可以通过下面的方式进行计算
import collections
isinstance(dict_keys, collections.Iterable)
isinstance(dict_values, collections.Iterable)
isinstance(map, collections.Iterable)
isinstance(range, collections.Iterable)
可以清楚地区分新对象是否可编辑,但与问题的标题相似,那么位置/关键字参数的操作如何
到目前为止,所有对象都替换为支持星号操作的列表
,作为我的测试,但我需要明确的标准,而不是手动测试
我试过几种方法,但没有共同的标准
它们都是Iterable
class?
- 否,
Iterable
生成器不支持
它们都是迭代器类?
- 否,
迭代器
生成器
不支持
它们都是容器
类?
- 否
映射
类不是容器
它们都有一个共同的超类
类?
- 不,没有公共超类(使用
Class.mro()测试)
我怎么知道对象是否支持位置/关键字参数的操作
单星号格式(*args)用于传递非关键字,
可变长度参数列表,并使用双星号形式
传递关键字可变长度参数列表的步骤
每个可数“支持”带星号的表达式;就连发电机和地图也有。然而,“一个对象支持*
”是一个误导性的术语,因为星号的意思是“解包我的interable并将每个元素传递给接口的参数”。因此,*
操作符支持可伸缩性
这可能就是你的问题所在:与*
一起使用的iterables必须具有与接口具有参数一样多的元素。例如,请参见以下代码段:
# a function that takes three args
def fun(a, b, c):
return a, b, c
# a dict of some arbitrary vals:
d = {'x':10, 'y':20, 'z':30} # 3 elements
d2 = {'x':10, 'y':20, 'z':30, 't':0} # 4 elements
您可以通过多种方式将d
传递给乐趣:
fun(*d) # valid
fun(*d.keys()) # valid
fun(*d.values()) # valid
但是,您不能将d2
传递给fun
,因为它有更多的元素
fun
接受参数:
fun(*d2) # invalid
def genx():
for i in range(3):
yield i
fun(*genx()) # Result: (0, 1, 2)
您还可以使用表达式将贴图传递到fun
。但是请记住,map
的结果必须具有与fun
获取参数一样多的参数
def sq(x):
return x**2
sq_vals = map(sq, *d.values())
fun(*sq_vals) # Result (100, 400, 900)
如果生成器生成的元素数量与函数接受的参数数量相同,则同样适用:
fun(*d2) # invalid
def genx():
for i in range(3):
yield i
fun(*genx()) # Result: (0, 1, 2)
为了检查是否可以使用星号表达式将iterable解压到函数的接口中,需要检查iterable的元素数是否与函数的参数数相同
def sq(x):
return x**2
sq_vals = map(sq, *d.values())
fun(*sq_vals) # Result (100, 400, 900)
例如,如果您希望针对不同长度的参数使函数安全,可以尝试以下方式重新定义函数:
# this version of fun takes min. 3 arguments:
fun2(a, b, c, *args):
return a, b, c
fun2(*range(10)) # valid
fun(*range(10)) # TypeError
我知道它们是什么,我只想知道哪些对象支持该操作,以及对象是否支持的标准是什么。感谢您的回答,我似乎对generator进行了漏检。