Python内置函数: __nonzero__

本文介绍了Python类的__nonzero__方法,它用于将类转换为布尔值。当进行布尔判断或转换时,该方法会被调用。官方定义表明__nonzero__在bool()函数中起到关键作用,若未定义则会尝试调用__len__方法。通过一个XML解析的应用例子,展示了__nonzero__在实际编程中的应用,强调了深入理解语言特性的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

类的__nonzero__方法用于将类转换为布尔值。通常在用类进行判断和将类转换成布尔值时调用。

官方定义

查看Python手册,对此内置函数的定义如下:

object.__nonzero__(self) 
	Called to implement truth value testing and the built-in operation bool(); 
	should return False or True, or their integer equivalents 0 or 1. When this 
	method is not defined, __len__() is called, if it is defined, and the object 
	is considered true if its result is nonzero. If a class defines neither 
	__len__() nor __nonzero__(), all its instances are considered true.

来研究一下Python中常见的"if obj:"逻辑判断语句,Python内部是如何处理的。从手册的定义中,__nonzero__实现了对布尔逻辑值的检查,是bool()函数的内置操作。该函数返回False或True的布尔值,或者对应的整数值0或1. 如果这个函数没有定义,便会调用内置函数__len__(). 如果__len__()已经定义,则返回值非0,则认为对象为true。如果类未实现__len__()和__nonzero__(),则实例对象被认为是true。

应用举例

今天同事咨询了一个关于XML解析的问题,用Python xml库去解析一个XML文件,查询一个标签:

pointA = e.find('PointA')
if pointA:
	do_something()
else:
	do_otherthing()
标签明明存在,为什么程序会运行到else语句中。平时我一般都会写成"if pointA is not None:",也没深究过这个问题, 决定研究一下。

首先,查看一下find的源码,

    ##
    # Finds the first matching subelement, by tag name or path.
    #
    # @param path What element to look for.
    # @keyparam namespaces Optional namespace prefix map.
    # @return The first matching element, or None if no element was found.
    # @defreturn Element or None

    def find(self, path, namespaces=None):
        return ElementPath.find(self, path, namespaces)
从源码中看,接口返回Element或None, 因此判断标签是否存在,需要写成"if pointA is not None:"。那如果是按照之前方式写,有什么问题呢? 根据Python对对象逻辑值转换的方式,需要研究一下内部实现:

class Element(object):
	......
    ##
    # Returns the number of subelements.  Note that this only counts
    # full elements; to check if there's any content in an element, you
    # have to check both the length and the <b>text</b> attribute.
    #
    # @return The number of subelements.

    def __len__(self):
        return len(self._children)

    def __nonzero__(self):
        warnings.warn(
            "The behavior of this method will change in future versions.  "
            "Use specific 'len(elem)' or 'elem is not None' test instead.",
            FutureWarning, stacklevel=2
            )
        return len(self._children) != 0 # emulate old behaviour, for now
从__nonzero__()函数的内部实现中,我们可以看出,实际上对于Element对象转换为布尔值时,是基于该对象是否是XML的叶子节点。如果是叶子节点的话,布尔转换为False.  根据这段代码实现,和内置函数的定义,可以清楚的了解了Element对象转换为布尔值的内部逻辑。

总结

在实际编程过程中,遇到类似问题时,不确定的情况下,还是需要查一下手册,深究一下语言特性,否则,可能会被一些奇怪的现象所困惑。深究的过程,也是学习和提高的过程,技术积累无捷径。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值