检测Python中的kwarg覆盖
我正在寻找一种方法来检测关键字arg是否被显式传入,而不使用检测Python中的kwarg覆盖,python,Python,我正在寻找一种方法来检测关键字arg是否被显式传入,而不使用**kwargs 以下是一个例子: def foo(first, second=None): pass 如果在此函数中,我发现second包含None,是否有办法知道该None是默认值还是显式传入的?基本上,我有一个可选参数,可以是任何值或类型。因此,我要么需要某种“唯一”的默认值,这样用户就不会有意地传入该默认值,要么需要一种方法来检测参数是否确实显式传入 我希望我可以通过检查堆栈来发现它,但我觉得这太过分了 我也知道我可以
**kwargs
以下是一个例子:
def foo(first, second=None):
pass
如果在此函数中,我发现second
包含None
,是否有办法知道该None
是默认值还是显式传入的?基本上,我有一个可选参数,可以是任何值或类型。因此,我要么需要某种“唯一”的默认值,这样用户就不会有意地传入该默认值,要么需要一种方法来检测参数是否确实显式传入
我希望我可以通过检查堆栈来发现它,但我觉得这太过分了
我也知道我可以这样做:
def foo(first, **kwargs):
if 'second' in kwargs:
# Overridden!
pass
但我不愿意接受
**kwargs
,因为它会降低我的函数签名的实用性并隐藏错误。您可以始终创建一个唯一的对象并将其用作默认值:
_default = object()
def foo(first, second=_default):
if second is not _default:
# Overridden!
pass
完全正确:使用不是None
的。很多时候,任何旧物体都可以
\u default=object()
有一个缺点:\u default
不共享None
的便利属性,即在条件语句中逻辑上等于False
。也就是说,None
是“假的”,但是\u default
是“真的”。更正式地说,bool(None)==False
但是bool(\u default)==True
如果您可以创建新的NoneType
实例,使其类似于None
,但不完全是None
,那就太好了。但是不能进一步实例化NoneType
。不过,您可以创建一个类似的类。因此:
import sys
_PY3 = sys.version_info[0] == 3
class NullType(object):
"""
A 'null' type different from, but parallel to, None. Core function
is representing emptyness in a way that doesn't overload None.
This helps create designated identifiers with specific meanings
such as Passthrough, Prohibited, and Undefined.
Instantiate to create desired null singletons. While they are
singletons, depends on usage convention rather than strict
enforcement to maintain their singleton-ness. This is a problem
roughly 0% of the time.
"""
def __init__(self, name=None):
self.name = name
def __repr__(self):
if self.name is not None:
return self.name
else:
return 'NullType(id: {0})'.format(id(self))
if _PY3:
def __bool__(self):
"""I am always False."""
return False
else: # PY2
def __nonzero__(self):
"""I am always False."""
return False
将该代码放入nulltype.py
中,然后:
from nulltype import NullType
_default = NullType('_default')
def foo(first, second=_default):
if second is not _default:
# Overridden!
pass
但你也可以做到:
if second:
...
(在某些上下文中)因为second
的真值等于None
。如果您使用了更简单的\u default=object()
sentinel,则无法执行此操作,因为bool(object())==True
现在,
\u默认值
是唯一的,在需要打印时可以很好地打印,并且总是等同于False
。这是你自己的私人None
除了使用不可怕的**kwargs
之外,然后使用哨兵值。。。例如sentinel=object()
然后检查如果second不是sentinel
…谢谢,这太完美了。我喜欢它!我将把NPE的答案标记为真实答案,但这非常有用,谢谢!他的作品绝对具有简洁和内在的美。