是否存在别名函数args的语法?如果没有,是否有任何PEP提案?我不是编程语言理论家,所以我的观点可能不知情,但我认为实现某种函数arg别名可能很有用。
我正在对libcloud进行一些更改,我的想法可以帮助我在修改API时避免破坏其他人。
例如,假设我正在重构,并希望将函数arg'foo'重命名为'bar':
原件:
def fn(foo):
<code (using 'foo')>
我可以:
def fn(foo, bar=None):
if foo and bar:
raise Exception('Please use foo and bar mutually exclusively.')
bar = foo or bar
<code (using 'bar')>
# But this is undesirable because it changes the method signature to allow
# a new parameter slot.
fn('hello world', 'goodbye world')
我未精制的句法糖理念:
def fn(bar|foo|baz):
# Callers can use foo, bar, or baz, but only the leftmost arg name
# is used in the method code block. In this case, it would be bar.
# The python runtime would enforce mutual exclusion between foo,
# bar, and baz.
<code (using 'bar')>
# Valid uses:
fn(foo='hello world')
fn(bar='hello world')
fn(baz='hello world')
fn('hello world')
# Invalid uses (would raise some exception):
fn(foo='hello world', bar='goodbye world')
fn('hello world', baz='goodbye world')
答案 0 :(得分:3)
不,没有这样的语法糖。
您可以使用**kwargs
来捕获额外的关键字参数,并在其中查找已弃用的名称(如果没有,则引发异常)。你甚至可以用装饰器自动化它。
from functools import wraps
def renamed_argument(old_name, new_name):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if old_name in kwargs:
if new_name in kwargs:
raise ValueError(
"Can't use both the old name {} and new name {}. "
"The new name is preferred.".format(old_name, new_name))
kwargs[new_name] = kwargs.pop(old_name)
return func(*args, **kwargs)
return wrapper
return decorator
@renamed_argument('bar', 'foo')
def fn(foo=None):
<method code>
演示:
>>> @renamed_argument('bar', 'foo')
... def fn(foo=None):
... return foo
...
>>> fn() # default None returned
>>> fn(foo='spam')
'spam'
>>> fn(bar='spam')
'spam'
>>> fn(foo='eggs', bar='spam')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in wrapper
ValueError: Can't use both the old name bar and new name foo. The new name is preferred.
答案 1 :(得分:2)
没有,你可以使用装饰器(如上所示),或者第一手使用kwargs:
<div class="intpol1"> Test</div> <div class="intpol3"> Test3</div> <div class="intpol2"> Test2</div> <div class="intpollink"> Testlink</div>
您也可以使用可调用对象来执行此操作,如果需要,甚至可以在运行时将语法和行为引入解释器。
但在我看来,将此作为有效的Python语法引入并不是Pythonic,即使有PEP也不会发生。
正如您所看到的,您可以在不污染Python语法的情况下执行您想要的操作。
我并不是说你的例子在语法上不清楚,只是不必要。