Mat*_*ttS 42 python types boolean
我正在寻找f()某种类似于此的映射函数:
f(str) = ''
f(complex) = 0j
f(list) = []
Run Code Online (Sandbox Code Playgroud)
这意味着它返回一个类型的对象,该对象在转换为时被计算False为bool.
这样的功能存在吗?
Ara*_*Fey 66
不,没有这样的映射.并非每种类型的对象都具有虚假价值,而其他对象则具有多种价值.由于可以使用该__bool__方法自定义类的真值,因此理论上类可以具有无限数量的(不同的)虚假实例.
也就是说,大多数内置类型在没有参数的情况下调用构造函数时会返回其伪值:
>>> str()
''
>>> complex()
0j
>>> list()
[]
Run Code Online (Sandbox Code Playgroud)
jua*_*aga 26
不,一般来说,可能没有这样的价值.关于如何实现类型的真值,Python 数据模型非常松散:
object.__bool__(self)被称为实施真值测试和内置操作bool(); 应该返回False或True.如果未定义此方法,
__len__()则调用此方法( 如果已定义),如果其结果为非零,则将该对象视为true.如果一个类既未定义也__len__()未定义__bool__(),则其所有实例都被视为真.
所以考虑:
import random
class Wacky:
def __bool__(self):
return bool(random.randint(0,1))
Run Code Online (Sandbox Code Playgroud)
应该f(Wacky)返回什么?
并非所有类型都具有这样的价值.其他人可能有很多这样的价值.这样做的最正确的方法是创建一个类型到值的dict,因为那样你可以检查一个给定的类型是否在dict中,如果有多个选项你可以选择哪个值是正确的.缺点当然是您必须以某种方式注册您感兴趣的每种类型.
或者,您可以使用一些启发式编写函数.如果你对你传递给函数的内容非常小心,它可能会有一些限制.例如,您显示的所有情况除外complex是用于概括的容器cls().
complex实际上也是这样的,但我单独提到它,因为int并float没有.因此,如果您尝试使用空构造函数失败,则返回一个真实的对象或者提升一个TypeError,您可以尝试cls(0).等等等等...
更新
@ juanpa.arrivillaga的答案实际上暗示了一个适用于大多数课程的聪明的解决方法.您可以扩展该类并强制创建一个假实例但与原始类相同的实例.你必须通过扩展来做到这一点,因为类似的dunder方法__bool__只能在类上查找,而不是在实例上查找.还有许多类型,这些方法无法在实例上替换.正如@ Aran-Fey现在删除的评论指出的那样,你可以选择性地打电话,object.__new__或者t.__new__,根据你是否正在处理一个非常特殊的情况(如int):
def f(t):
class tx(t):
def __bool__(self):
return False
try:
return object.__new__(tx)
except TypeError:
return tx.__new__(tx)
Run Code Online (Sandbox Code Playgroud)
这只适用于您遇到的99.9%的课程.有可能创建一个人为的案例,TypeError当它传递给object.__new__as时int,并且不允许没有arg版本t.__new__,但我怀疑你会在自然界中找到这样的东西.请参阅@ Aran-Fey 的要点来证明这一点.