为什么我不能使用 "string".print() 方法?

7
我对Python和Ruby中的print()有一定的了解,它是字符串(或其他类型)上的方法。由于它非常常用,所以以下语法也可以使用:

print "hi"

那么为什么在Python中"hi".print()或者在Ruby中"hi".print不能正常工作呢?


如果你给一个字符串对象添加了一个打印方法,为什么要止步于此?系统中的每个对象都应该有一个打印方法。与切片、搜索等相比,打印似乎不是特别像字符串的操作。打印只是一种特定形式的I/O,并且你不会看到像整数和字符串这样的对象具有一个接受文件句柄作为参数的写入方法。 - Tim Hoffman
2
为什么这个问题会得到这么多赞,实际上它只是在问“为什么我不能随便打一些东西然后让它运行”?这什么时候变成了从完全无知的角度来接近一门语言的问题? - Matthew Trevor
@MatthewTrevor:放轻松。这个问题是关于什么成为方法,什么成为全局函数等背后的逻辑。 - Ned Batchelder
1
这个问题的解释比我能够做到的要宽容得多。 - Matthew Trevor
嘿大家,我误解了某个东西的工作原理。一些好心人纠正了我并解释了我的错误。现在我知道了。这似乎是一件好事情。 - DorkRawk
1
考虑到echristopherson的回答,我不认为这是一个愚蠢的问题。 - Andrew Grimm
7个回答

9
当你执行类似于"hi".print()这样的操作时,你暗示字符串对象"hi"有一个print方法。实际上并非如此。相反,print是一个以字符串(或其他类型)作为输入的函数。

2
这只适用于Python。Ruby没有函数,只有方法。在Ruby中,printIO协议的一个方法,例如IO#printStringIO#print。此外,还有一个方便的方法Kernel#print,它基本上调用$>.print,其中$>是全局变量,表示默认输出IO流(通常,$>指向STDOUT,但不一定)。正是这个方便的方法使您可以仅使用print 'Hi'而不是$>.print 'Hi'STDOUT.print 'Hi' - Jörg W Mittag

4
Ruby有一个方法叫做Object#display (文档在这里),它会将对象的表示发送到当前输出流或指定的输出流。如果在irb中使用;来抑制返回值的打印,那么使用display时,即使刷新了输出流,也无法显示其输出内容。

点赞这个帖子,因为我不知道 Object#display,尽管我认为我不喜欢它的存在,因为任何给定的对象都会神奇地知道如何打印自己(因为 a:它应该看起来像 self.to_s 还是 self.inspect 等等,b:它怎么知道在哪里打印自己?$stdout 或 $stderr 或一些随机文件或套接字或什么?每个对象都需要知道流的信息,这是多么可怕的依赖关系)。 - Joshua Cheek
@Joshua Cheek:如果您没有指定要输出到的流,则会使用伪全局变量 $> 的值,直到我查找它之前我甚至不知道它的存在。 - echristopherson

2
为什么这会起作用?String类很少有void print方法,而且你永远不需要它们,因为标准的静态print函数可以打印这些字符串。需要注意的是:method(someObject)不一定与someObject.method()相同。

2
这段文字的翻译如下:

它不是一个字符串方法。在 Python 3 之前,它是一个语句(就像 breakimport 一样),你可以同时使用 print "hi"print("hi")。从 Python 3 开始,它被一个函数 替换,因此你不能再使用 print "hi"

打印是一个函数

打印语句已经被一个 print() 函数所取代,关键字参数取代了旧的打印语句的大部分特殊语法(PEP 3105)。


2
你认为 str.print 应该做什么?
打印到标准输出?还是标准错误?或者文件?或串口?
打印到标准输出确实是一个特殊情况,但它非常普遍,有时可能会被忽视。
那么每次创建字符串时我们都必须指定 str 应该打印到哪里吗?
至少我们得说一下。
"foo".print(sys.stdout)

希望这看起来对你也很糟糕。这是责任混淆的表现。


0

print在Python(或Ruby,我相信)中不是字符串的方法。它是一个语句(在Python 3中它是一个全局函数)。为什么?首先,并不是你可以打印的所有内容都是字符串。比如print 2怎么办?


我不确定,但认为Ruby中没有语句或保留字。只有一个方法http://ruby-doc.org/core-1.9.3/ARGF.html#method-i-print - Иван Бишевац

-1
如果你更喜欢在 Ruby 中使用方法而不是语句,你可以使用方法 display ("test".display) 来实现这一点,或者轻松地定义一个新的方法,例如:
class String
  def print
    puts self
  end
end

并像这样使用它

"test".print

这样的猴子补丁对象通常是一个不好的习惯,特别是在像这样创建庞大依赖关系的情况下。我知道在这种情况下它不会咬你,因为print在Kernel中,但这只是一个例外(可以写一篇整篇博客)。 - Joshua Cheek
每个人都有自己的观点,我认为这里除了在代码中使用方法时必须在某处定义之外,没有其他依赖关系。 - peter
它取决于IO流和全局变量$stdout - Joshua Cheek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接