在python中,是否存在某种类型的映射来返回;“假值”;类型?

在python中,是否存在某种类型的映射来返回;“假值”;类型?,python,types,boolean,Python,Types,Boolean,我正在寻找一种映射函数f(),它的功能类似于: f(str) = '' f(complex) = 0j f(list) = [] 这意味着,当强制转换为bool时,它返回类型为False的对象 这样的函数存在吗?不,没有这样的映射。并不是每种类型的对象都有错误的值,而其他类型的对象有不止一个错误的值。由于类的真值可以通过自定义,因此理论上一个类可以有无限多(不同)的falsy实例 也就是说,大多数内置类型在没有参数的情况下调用构造函数时返回其falsy值: >>> str()

我正在寻找一种映射函数
f()
,它的功能类似于:

f(str) = ''
f(complex) = 0j
f(list) = []
这意味着,当强制转换为
bool
时,它返回类型为
False
的对象


这样的函数存在吗?

不,没有这样的映射。并不是每种类型的对象都有错误的值,而其他类型的对象有不止一个错误的值。由于类的真值可以通过自定义,因此理论上一个类可以有无限多(不同)的falsy实例

也就是说,大多数内置类型在没有参数的情况下调用构造函数时返回其falsy值:

>>> str()
''
>>> complex()
0j
>>> list()
[]

不,一般来说,可能没有这样的值。Python对于如何实现类型的真值非常松散:

object.\uuuubool\uuuuuu(self)

调用以实现真值测试和内置操作 bool();应该返回False或True。如果未定义此方法,
\uuuu len\uuuu()
被调用(如果已定义),如果对象的结果为非零,则该对象被视为true。如果一个类既不定义
\uuuu len\uuuu()
也不是
\uuubool\uuuuu()
,它的所有实例都被认为是真的

因此,请考虑:

import random
class Wacky:
    def __bool__(self):
        return bool(random.randint(0,1))

f(古怪)
应该返回什么?

并非所有类型都有这样的值。其他人可能有许多这样的价值观。最正确的方法是创建一个类型到值的dict,因为这样可以检查dict中是否有给定的类型,如果有多个选项,可以选择哪个值是正确的。缺点当然是,您必须以某种方式注册您感兴趣的每种类型

或者,您可以使用一些启发式方法编写函数。如果您对传递到函数中的内容非常小心,它可能会有一些有限的用途。例如,除了
complex
之外,您显示的所有案例都是使用
cls()泛化的容器

complex
实际上也是这样工作的,但我单独提到它,因为
int
float
不这样做。因此,如果使用空构造函数的尝试因返回truthy对象或引发
TypeError
而失败,则可以尝试
cls(0)
。诸如此类

更新

实际上,这是一个聪明的解决方案,适用于大多数类。您可以扩展该类并强制创建一个实例,该实例将是falsy,但在其他方面与原始类相同。您必须通过扩展来实现这一点,因为像
\uuuu bool\uuuu
这样的dunder方法只在类上查找,而不在实例上查找。还有许多类型的实例上无法替换这些方法。正如@Aran Fey现在删除的评论所指出的,您可以有选择地调用
对象。
t.。\uuuuuuuuuuuuuuuuuuuuuuuuuu
,这取决于您是否在处理非常特殊的情况(如
int
):


这只适用于你所遇到的99.9%的课程。当传递给
对象时,可以创建一个引起
TypeError
的人为事例。就像
int
一样,不允许使用
t的无参数版本。但是我怀疑你在自然界中是否会发现这样的事情。请参阅@Aran Fey来演示这一点。

这实际上被称为an,在编程中通常被视为a定义的一部分。在python中,可以使用包中的
mzero
函数为类型获取它。哈斯克尔称之为

不存在这样的函数,因为通常不可能。一个类可能没有falsy值,或者它可能需要反转
\uuu bool\uuu
的任意复杂实现

通过破坏所有其他内容,您可以构造该类的一个新对象,并将其
\uuubool\uuu
函数强制分配给返回
False
的对象。尽管我怀疑您正在寻找一个对象,否则该对象将是该类的有效成员


无论如何,这在经典风格中是一个非常糟糕的主意。

并不总是有这样一个值为什么要这样做?@Veedrac我想编写一个智能iff函数,它的默认假值(如果没有显式传递)将是真值类型的假对象。因此,如果签名类似于(cond,t,f),并且f是可选的,并且没有通过,那么它将被设置为type(t)(),我认为这只是将问题向下推了一级。这似乎不是一个基本的技术问题。@Veedrac在我看来,这是一种实现空对象模式的尝试:与其返回
None
,不如返回一个行为与预期类型类似但不执行任何操作的对象。这样就不必一直检查
None
,也不必检查python2@juanpa.arrivillaga. 我在更新中开始研究(作弊)解决方案,但它只适用于不允许arg构造函数的类。也许你可以建议一个解决方法?你是对的,也许要求一个通用的内置函数太多了。但我对此类函数的使用在大多数情况下都是微不足道的,我计划在不明确定义映射的情况下将其用于常见的标准python类型。“一个类理论上可以有无限多(不同)的falsy实例”或零,就这一点而言
type()
range()
memoryview()
失败,出现
TypeError
,因为它们需要参数。而其他类型,如模块和类,可能并不那么相关。据我所知,这不会为任何内置类型返回真实值。@RemcoGerlich:您忘记测试
object()
,它是真实的。如果计算异常,我相信所有内置异常类型都会返回一个真实值
def f(t):
    class tx(t):
        def __bool__(self):
            return False
    try:
        return object.__new__(tx)
    except TypeError:
        return tx.__new__(tx)