Python 中的一切都像 Ruby 一样是对象吗?

Posted

技术标签:

【中文标题】Python 中的一切都像 Ruby 一样是对象吗?【英文标题】:Is everything an object in Python like Ruby? 【发布时间】:2010-10-26 08:09:14 【问题描述】:

我在另一个 Stack Overflow 问题上读到 Python 就像 Ruby,因为它与“一切都是对象”有关,而 Python 中的一切都是对象,就像 Ruby。

这是真的吗?像 Ruby 一样,Python 中的一切都是对象吗?

两者在这方面有何不同,还是真的相同?例如,你能拿一个数字做我见过的 Ruby 的东西吗:

y = 5.plus 6

这可以在 Python 中以同样的方式完成吗?

【问题讨论】:

当您说“对象”时,您指的是 OOP 术语吗? python 和 ruby​​ 都是相当新手的语言,所以如果你真的问它与 Smalltalk、C++ 或从任何特定语言抽象的 OOP 范式(理论)相关,你的问题对我来说更有意义:“python 是一种纯 OO 语言吗?即每个(数据)类型都是一个对象(或一类对象)?” en.wikipedia.org/wiki/Object-oriented_programming 另见: ***.com/questions/192649/… 【参考方案1】:

DiveIntoPython - Everything Is an Object

Python 中的一切都是对象,几乎所有东西都有属性和方法。所有函数都有一个内置属性__doc__,它返回函数源代码中定义的doc stringsys 模块是一个对象,它具有(除其他外)一个名为 path 的属性。以此类推。

不过,这引出了一个问题。什么是对象?不同的编程语言以不同的方式定义“对象”。在某些情况下,这意味着所有对象必须具有属性和方法;在其他情况下,这意味着所有对象都是可子类化的。在 Python 中,定义比较宽松;有些对象既没有属性也没有方法(第 3 章会详细介绍),而且并非所有对象都是可子类化的(第 5 章会详细介绍)。但从某种意义上说,一切都是对象,它可以分配给变量或作为参数传递给函数(第 4 章会详细介绍)。

Ruby Docs - To Ruby From Python

与 Python 一样,在 Ruby 中,...一切都是对象

你可以从 Ruby 自己的网站获得它:在 Python 中,一切都是对象。

【讨论】:

+1 说得好。作为一名 Rubyist,我倾向于“对象必须有方法”这一论点,但“一切都可以作为参数传递”的论点说得很好(我怀疑更好地反映了 Pythonista 的观点) “但从某种意义上说,一切都是对象,它可以分配给变量或作为参数传递给函数(第 4 章会详细介绍)。”这对我来说没有任何意义。这不会使 Java 成为 int 对象吗? @JamesMcMahon 是的,你是对的!以上回答没有回答问题!!如果我们阅读 Guido 的 blog,它会说:One of my goals for Python was to make it so that all objects were "first class." By this, I meant that I wanted all objects that could be named in the language (e.g., integers, strings, functions, classes, modules, methods, etc.) to have equal status. That is, they can be assigned to variables, placed in lists, stored in dictionaries, passed as arguments, and so forth. 我也可以说:“对象在某种意义上是用与其他对象相同的 CPython 中挂钩的固有结构/位置实现的”... 我认为普遍的理解是对象是方法和字段的容器,其中对这些内部方法和字段的访问由对象本身控制。这意味着,要执行方法或从字段读取/写入,您必须要求对象为您执行操作。我不知道 python,但看起来它可能不符合这个定义。我认为您可以创建一种语言,其中在运行时绝对一切都是这样,并且所有对象都将包含在主对象中,因此即使引用相等也可能是主对象的一种方法。【参考方案2】:

虽然在 Python 中一切都是对象,但它在解析名称和与对象交互的方法上与 Ruby 不同。

例如,虽然 Ruby 在 Object 基类上为您提供了一个“to_s”方法,但为了公开该功能,Python 将其集成到字符串类型本身 - 您可以通过从它。你有str(5),而不是5.to_s

不过,不要上当。幕后还有一个方法——这就是这段代码有效的原因:

(5).__str__()

所以在实践中,两者基本相似,但你使用它们的方式不同。 Python 中的列表和元组等序列的长度是这一原则的另一个例子 - 实际功能基于 methods with special names,但通过更简单、更易于使用的接口(@98​​7654325@ 函数)公开。

因此,与您在问题中所写的 Python 等效的是:

(5).__add__(6)

另一个重要的区别是全局函数的实现方式。在 Python 中,全局变量由字典表示(本地变量也是如此)。这意味着以下内容:

foo(5)

在Python中相当于这个:

globals()["foo"].__call__(5)

虽然 Ruby 有效地做到了这一点:

Object.foo(5)

这对用两种语言编写代码时使用的方法有很大影响。 Ruby 库倾向于通过向现有类型(如 Object)添加方法来增长,而 Python 库倾向于通过向给定模块添加全局函数来增长。

【讨论】:

“Python 库倾向于通过向给定模块添加全局函数来增长。”这并不正确。 globals()["foo"] 返回一个对象。 call 是一种方法,而不是全局函数。你不能做 globals()["call"] 我的意思是 foo 不是模块的方法。它是模块的一个属性,恰好是可调用的,导入它也会将它添加到 globals() 中。 call 是一种方法,是的。相比之下,在 Ruby 中 foo 是 Object 的一种方法。 我试图理解为什么我可以做 "1".__eq__("2") => False,而不是 1.__eq__(2) => SyntaxError: invalid syntax。您的回答表明我需要括号,例如 (1).__eq__(2)。奇怪的是,@RichieHindle 的 1..__add__(2) 有效,但不是一个句号。这是为什么呢? @MatthewCornell 我认为是因为在十进制后的 1.__add__(5) 的情况下,解释器期待一些数字但发现 _ 这不是数字,因此会引发错误,但是在 1..__add__ 的情况下(5)、第二个小数除了调用某些属性或方法外,不能起到任何作用。【参考方案3】:

“everything”对于 Python 和 Ruby 来说都有些过高了——例如,if 不是“对象”,而是用于启动条件语句或(在 Python 中)在列表中的关键字推导式和生成器表达式。发现函数、类、方法和所有类似的东西在(比如)C++ 中不是真正的对象,在 Ruby 或 Python 中是对象的热情,引起了这种热情。其他东西可能是 Ruby 中的对象,但不是 Python 或反之亦然(代码块、正则表达式……)。

【讨论】:

是的,但即使在 smalltalk 上,'if' 是一种块方法(红宝石上的 Proc/lambda,python 上的 lambdas,与语言无关的人的闭包),一切都是对象,有它的关键字 true、false、nil、self、super 和 thisContext。果然,这些更像是伪变量......【参考方案4】:

回答你的第二个问题,是的:

>>> (1).__add__(2)
3

【讨论】:

是的。甚至1. __add__(2)(注意空格)。甚至适用于花车:1..__add__(2). @dF:您的第一个示例在“1.”之后使用空格,在 3.2.3 中对我不起作用 => SyntaxError: invalid syntax 空格应该在 1 和点之间 :D 1 .__add__(2)【参考方案5】:

是的,据我所知,Python 中的一切都是对象。当然,原始类型和内置类型(int、long、str、float 等)可以被子类化——实际上这些类型本身就是对象。函数是对象,类是对象,甚至代码块在某种意义上也是对象……我想不出 Python 中有什么东西不能被当作对象来对待。

【讨论】:

# comment 是一个对象吗?这不是批评。我真的很好奇。 @ocertat 不,至少不是我认为你的意思。注释是源代码的一个特性,但不是程序本身的特性。当 Python 解析器运行时,它会简单地丢弃注释中的任何文本并且不对其进行操作。 (但是,标准库中有一个 Python 源代码解析器,如果您在带有 cmets 的源文件上运行它,它可能会生成与这些 cmets 相对应的对象——我不记得它是否这样做了。) 我不认为if 是一个对象。【参考方案6】:

为其他人的优秀答案添加评论:一切都是对象,但有些——特别是字符串和数字类型——是不可变的。这意味着这些类型在赋值、参数传递等方面的行为方式与它们在 C 或 Java(其中整数等不是对象)等语言中的行为方式相同,并且您永远不必担心由传递引起的陷阱-参考。这是一个很好的解决方案:-)

【讨论】:

【参考方案7】:

你好,答案不是一切,参考比这更完整,并提供更多途径,例如在 Python 3.8.5 中,分隔符、运算符和关键字不是对象。 ***.com/a/66374328/11554034

已在该链接中详细解释了它,请随时查看。

无论如何,下一个说你可以通过说来纠正它(更正确的东西,尽管如果仍然可以更完整,请随意): “逻辑行中除 NEWLINE、INDENT、DEDENT、空格键字符、运算符、关键字或分隔符之外的所有内容都是 Python 中的对象。”

干杯。

【讨论】:

以上是关于Python 中的一切都像 Ruby 一样是对象吗?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 面向对象

雷林鹏分享:Ruby 面向对象

什么是“一流”对象?

如果在 Ruby 中一切都是对象,为啥这不起作用?

PHP 等价于 Ruby 符号

获取 ruby​​ 函数对象本身