Python len()和._ulen__u;()之间的区别?
调用Python len()和._ulen__u;()之间的区别?,python,Python,调用len([1,2,3])或[1,2,3]之间有什么区别吗 如果没有明显的差异,在幕后会有什么不同的做法?len是一个获取集合长度的函数。它通过调用对象的方法来工作\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 在很久以前的某个时候,人们决定获取某个东西的长度应该是一个函数,而不是一个方法代码,理由是len(a)的意思对于初学者来说是很清楚的,但是a.len()就不那么清楚
len([1,2,3])
或[1,2,3]之间有什么区别吗
如果没有明显的差异,在幕后会有什么不同的做法?len
是一个获取集合长度的函数。它通过调用对象的方法来工作<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
在很久以前的某个时候,人们决定获取某个东西的长度应该是一个函数,而不是一个方法代码,理由是len(a)
的意思对于初学者来说是很清楚的,但是a.len()
就不那么清楚了。当Python启动时,\uuu len\uuu
甚至不存在,len
是一种特殊的东西,可以处理几种类型的对象。不管这种情况是否完全有意义,它都将继续存在。你可以认为len()大致相当于
def len(x):
return x.__len__()
一个优点是它可以让你写像这样的东西
somelist = [[1], [2, 3], [4, 5, 6]]
map(len, somelist)
而不是
map(list.__len__, somelist)
或
不过,他们的行为略有不同。
例如,在ints的情况下
>>> (1).__len__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__len__'
>>> len(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>>(1)。\uu len
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“int”对象没有属性“\uuuu len\uuuu”
>>>len(1)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:类型为“int”的对象没有len()
通常情况下,内置or运算符的“典型”行为是(使用不同且更好的语法)在所涉及的对象上调用合适的魔术方法(名称为\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu等)。通常,内置or运算符具有“附加值”(它能够根据所涉及的对象选择不同的路径)——在len
vs\uuuuu len\uuuu
的情况下,只是对魔术方法中缺少的内置对象进行了一点健全性检查:
>>> class bah(object):
... def __len__(self): return "an inch"
...
>>> bah().__len__()
'an inch'
>>> len(bah())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object cannot be interpreted as an integer
>>类bah(对象):
... 定义长度(self):返回“一英寸”
...
>>>呸()。______()
“一英寸”
>>>len(bah())
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“str”对象不能解释为整数
当您看到对内置len
的调用时,您可以确定如果程序在此之后继续而不是引发异常,则调用已返回一个整数、非负,并且,您可以检查:
嗯,len(s)
是一个内置的Python方法,它返回对象的长度。现在,\uu len\uu()
是一个特殊的方法,由len(s)
方法在内部调用,以返回对象的长度
因此,当我们调用len(s)
方法时,s.\uu len\uuu()
就是在幕后实际发生的事情来计算长度
Pythonlen()
函数可以解释为:
def len(s):
return s.__len__()
看,我是Python初学者用户(不是初学者程序员认为的那样),我不确定“当您看到对len内置函数的调用时,您可以确定,如果程序在此之后继续运行,而不是引发异常”。我试过这样做:def len(x):返回“我是一个字符串”。print(len(42))print(len([1,2,3])
它将I am string
打印了两次。你能再解释一下吗?@DarekNędza这与上述内容无关,这是关于内置透镜的。您刚刚定义了len函数,它当然可以返回您想要的任何结果。OP谈到了内置函数len,它在考虑中的对象上调用\uuuLen\uUn
特殊方法(而不是函数)。@Veky我如何确定我调用的是内置函数len
,而不是其他碰巧同名的函数(如我的示例中的函数-len
)。没有类似“您正在重新定义内置函数len”之类的警告。在我看来,我不能确定Alex在回答中说了什么。Alex明确地说,如果你打电话给builtin,那么你肯定…\。他没说要确定你打电话给builtin。但是如果您想知道这一点,您可以:len in vars(\uuuu builtins\uuuu).values()
。遗憾的是,这是Python中缺少通用对象基类的另一个例子。句法语境转换一直都很疯狂。在某些情况下,使用下划线方法是常见的习惯用法,在另一些情况下,应该使用函数之类的方法来完成许多对象的通用操作。这也很奇怪,因为许多对象对len没有语义用途。有时对象模型更像C++,厨房脏兮兮……我假设你是指<代码>运算符。方法调用程序< /> >而不是<代码>运算符。
>>> class Meta(type):
... def __getattribute__(*args):
... print "Metaclass getattribute invoked"
... return type.__getattribute__(*args)
...
>>> class C(object):
... __metaclass__ = Meta
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print "Class getattribute invoked"
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
def len(s):
return s.__len__()