Python 在Ruby中,为什么'Array.length'给出nomethoderor?

Python 在Ruby中,为什么'Array.length'给出nomethoderor?,python,ruby,nomethoderror,name-lookup,Python,Ruby,Nomethoderror,Name Lookup,在Python中,我可以通过调用\uu len\uu方法来获取列表的长度\uuuu len\uuuu不是在每个列表对象上定义的,而是在列表类上定义的。可以通过类直接访问该方法: >>> [].__len__() 0 >>> type([]) <class 'list'> >>> list.__len__([]) 0 为什么在使用Array.length时找不到length方法?Ruby中的方法查找与Python中的不同吗?是的,

在Python中,我可以通过调用
\uu len\uu
方法来获取
列表的长度<代码>\uuuu len\uuuu
不是在每个
列表
对象上定义的,而是在
列表
类上定义的。可以通过类直接访问该方法:

>>> [].__len__()
0
>>> type([])
<class 'list'>
>>> list.__len__([])
0

为什么在使用
Array.length
时找不到
length
方法?Ruby中的方法查找与Python中的不同吗?

是的,Ruby中的方法查找与Python中的方法查找有很大的不同

TL;答案是,如果您确实想从
Array
类对象中提取
length
方法,您需要编写
Array.instance\u方法(:length)
。这将获得一个
UnboundMethod
对象,然后可以将其绑定到特定对象并调用:

unbound_method = Array.instance_method(:length)
ary = [1,2,3,4]
bound_method = unbound_method.bind(ary)
bound_method.call #=> 4
毫不奇怪,这在Ruby中并不常见

在Ruby中,类本身就是对象,类的实例
class
;这些类有自己的方法,除了它们为实例提供的方法之外,还有一些方法,如
new
name
超类
,等等。当然,可以在
数组
类对象上定义
length
方法,这样您就可以编写
Array.length
,但这与同名的实例方法没有内在的联系。在核心类和标准库中,有一些地方实际上是这样做的,但在大多数情况下,它在Ruby中不是惯用的

类对象直接响应的方法与它为其实例提供的方法之间的区别可以在
方法
实例方法
方法的输出中非常清楚地看到:

irb(main):001:0> Array.methods
=> [:[], :try_convert, :new, :allocate, :superclass, ...
irb(main):002:0> Array.instance_methods
=> [:each_index, :join, :rotate, :rotate!, :sort!, ...
Ruby中的方法查找不如Python中的方法查找工作的一个原因是,类和实例可能都需要以不同的方式响应某些方法名。例如,假设一个假设的人类:

Person.ancestors # => [Person, Animal, Organism, Object, Kernel, BasicObject]
john = Person.new(...)
john.ancestors # => [John Sr., Sally, Jospeh, Mary, Charles, Jessica]
当然,在Python中,第一个调用是错误的:如果不将
Person
的实例传递为
\uuuuuuu self\uuuu
,就不能调用
Person.concedens
,这没有任何意义。那么,你如何获得Person类的祖先呢?将
Person
自身传递给函数:
inspect.getmro(Person)
。这在Python中是惯用的,但在Ruby中被认为是非常糟糕的风格

本质上,作为不同的语言,尽管在许多方面它们是相似的,但它们解决某些问题的方法仍然不同,而一些在一种语言中被认为是好的实践或风格的东西在另一种语言中则相当糟糕(反之亦然)

Person.ancestors # => [Person, Animal, Organism, Object, Kernel, BasicObject]
john = Person.new(...)
john.ancestors # => [John Sr., Sally, Jospeh, Mary, Charles, Jessica]