我想要自定义 NotSet 值,该值可用于类似于 None 的类型提示。
NotSet = ?
class Client:
def partial_update(
self,
obj_id: int,
obj_field: int | None | NotSet = NotSet,
...
):
# Do not update fields which were not specified explicitly.
if obj_field is NotSet:
# do not update obj_field
else:
# update obj_field
...
解决方案不够好:
None
。ellipsis
:from types import EllipsisType
def partial_update(
obj_field: int | None | EllipsisType = ...,
):
pass
obj_field: int | None | ... = ...,
class NotSetType:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
NotSet = NotSetType()
def partial_update(
obj_field: int | None | NotSetType = NotSet,
):
pass
我认为你不能这样做,类不能是它自己的实例(除非它是
type
,但这是一个不同的故事)。
(其实可以:
class Meta(type):
def __new__(cls, name, bases, dct):
x = super().__new__(cls, name, bases, dct)
return x(name, bases, dct)
class NotSet(type, metaclass=Meta):
pass
def partial_update(
obj_field: int | None | NotSet = NotSet,
):
if obj_field is NotSet:
print('not updating')
else:
print(f'updating to {obj_field}')
>>> NotSet
<class '__main__.NotSet'>
>>> type(NotSet)
<class '__main__.NotSet'>
>>> partial_update()
not updating
>>> partial_update(None)
updating to None
>>> partial_update(4)
updating to 4
但是你的静态类型检查器可能不高兴,例如mypy 不是。)
我认为你的第三个选择是最Pythonic、最明确、最容易理解的。另一个建议是使用
**kwargs
而不是函数参数:
def partial_update(
**kwargs,
):
for field, value in kwargs.items():
setattr(obj, field, value)
尽管您丢失了类型提示和字段名称。