与继承的方法调用相比,具有len()、max()和min()等静态函数的优点

2024-03-29 05:27:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个python新手,我不知道python为什么把len(obj)、max(obj)和min(obj)实现为静态类函数(我来自java语言)对象(), 目标最大值(),和目标最小值()

使用len()有哪些优点和缺点(除了明显的不一致性之外)。。。在方法调用上?在

为什么guido选择这个而不是方法调用?(如果需要的话,这个问题可以在python3中解决,但是在python3中没有改变,所以一定有很好的理由…我希望)

谢谢!!在


Tags: 对象方法函数语言obj目标len静态
3条回答

它强调对象的功能,而不是它的方法或类型。Capabilites是由诸如__iter____len__等“helper”函数声明的,但它们并不构成接口。接口位于内置函数中,除此之外,还包含内置运算符,如+和[],用于索引和切片。在

有时,它不是一对一的对应关系:例如,iter(obj)返回一个对象的迭代器,即使没有定义__iter__,它也可以工作。如果没有定义,它将继续检查对象是否定义了__getitem__,并将返回一个按索引方式访问对象的迭代器(如数组)。在

这与Python的Duck类型结合在一起,我们只关心可以对一个对象做什么,而不关心它是一个特定类型。在

实际上,这些方法不是你所想的“静态”方法。它们是built-in functions,实际上只是对实现它们的python对象上的某些方法的别名。在

>>> class Foo(object):
...     def __len__(self):
...             return 42
... 
>>> f = Foo()
>>> len(f)
42

无论对象是否实现它们,都可以调用它们。关键是要有一些一致性。不同于某些类有一个名为length()和另一个名为size()的方法,惯例是实现len,并让调用方始终通过更可读的len(obj)来访问它,而不是不常见的目标方法在

最大的优点是内置函数(和运算符)可以在适当的时候应用额外的逻辑,而不仅仅是简单地调用特殊的方法。例如,min可以查看多个参数并应用适当的不等式检查,或者它可以接受一个iterable参数并以类似的方式进行;abs当在没有特殊方法的对象上调用时,__abs__可以尝试将所述对象与0进行比较,并在需要时使用对象更改符号方法(尽管目前没有);等等。在

因此,为了一致性,所有具有广泛适用性的操作必须始终通过内置和/或运算符,而这些内置的职责是查找和应用适当的特殊方法(在一个或多个参数上),在适用的情况下使用替代逻辑,等等。在

这个原则没有被正确地应用(但是在python3中这种不一致性得到了修复)是“step An iterator forward”:在2.5和更早版本中,您需要在迭代器上定义并调用非特殊命名的next方法。在2.6和更高版本中,您可以用正确的方式来做:迭代器对象定义__next__,新的next可以调用它并且应用额外的逻辑,例如提供一个默认值(在2.6中,为了向后兼容,您仍然可以用不好的旧方法来做,但是在3.*中,您不能再这样做了)。在

另一个例子:考虑表达式x + y。在传统的面向对象语言中(只能对最左边的参数进行调度——比如Python、Ruby、java、C++、C、C和C),如果^ {CD9}}是一些内置类型,^ {< CD10}}是您自己的新奇类型,如果语言坚持将所有逻辑委托给^ {CD11}}的方法,那么您将不幸落空。加法(假设语言允许运算符重载;-)。在

在Python中,+操作符(当然还有内置的operator.add,如果你喜欢的话)会尝试x的类型__add__,如果这个操作符不知道如何处理y,那么就尝试y的类型__radd__。因此,您可以定义知道如何将自身添加到整数、浮点、复数等中的类型,也可以定义知道如何将此类内置数字类型添加到自身的类型(即,您可以对其进行编码,使x + y和{}都能正常工作,当y是您喜欢的新类型的实例,x是某个内置数字类型的实例时)。在

“泛型函数”(如PEAK中的)是一种更优雅的方法(允许基于类型组合的任何重写,从不,疯狂的单项式关注OOP鼓励的最左边的参数!-),但(a)不幸的是,python3不接受它们,(b)它们确实要求泛型函数以独立的形式表示(将函数视为“属于”任何一个类型是绝对疯狂的,关键在于,可以根据其多个参数类型的任意组合来不同地重写/重载!-). 任何使用过通用Lisp、Dylan或PEAK编程的人都知道我在说什么;-)。在

因此,独立的函数和运算符是正确的、一致的方法(尽管在简陋的Python中,缺少泛型函数确实消除了一些固有优雅的部分,但它仍然是优雅和实用性的合理结合!-). 在

相关问题 更多 >