代码之家  ›  专栏  ›  技术社区  ›  ilya n.

为什么打印声明不是蟒蛇?[关闭]

  •  34
  • ilya n.  · 技术社区  · 15 年前

    这个问题困扰了我很长一段时间(如 my previous question ):为什么 print(x) print x ?

    对于那些不知道的人, print 语句在python 3.0中被更改为函数。正式文件在 PEP 3105 动机就在 Guido van Rossum's email .

    对于这些问题,我想做一个对位:

    1. 还有其他运算符,例如 import 虽然它们的功能实际上是用一个函数来复制的,但是我们把它们写成一个语句。 __import__
      • 对于初学者,操作员 打印 不属于一般应用程序逻辑。对他们来说,这是一个神秘的操作员,是他们程序的顶峰。他们希望它看起来不同。
      • 所有描述基本python 2.x的初学者书籍现在都是 保证与第一个例子不符 . 当然,语言有时会发生变化,但这些变化对于新手来说通常不太明显。
      • 对我来说,一个 打印 可以在应用程序级别上复制。例如,有时我想将控制台中的打印重定向为模式操作系统对话框。
      • 当人们说很难重写所有 打印 对于一个函数的语句,它们强制每个python 2.x开发人员为他们的所有项目都这样做。很好,自动转换器不难。
      • 喜欢操纵功能的人 打印 如果是这样的话 打印 是语句包装函数 __print__ .

    那么,我们能在堆栈溢出页面上对这个问题给出一个规范的答案吗?

    5 回复  |  直到 9 年前
        1
  •  56
  •   Alex Martelli    15 年前

    在我看来,你的回答是一场辩论,而不是一个问题——你真的会接受一个表明你在自己的断言中有多么严重错误的答案吗?!

    关于你的争论点:

    还有其他运算符,例如 导入我们作为语句编写的, 尽管它们的功能实际上是 用函数复制 __import__

    绝对错误:功能 进口商品 (像 每一个 其他函数——和运算符,就这点而言)绑定 “调用者”范围内的名称(包含它的代码)——绑定“调用者”范围内名称的任何“thingie” 必须 做一个陈述(就像作业一样, def call )。您的“要点”似乎完全忽略了python在语句和表达式之间所产生的极其深刻和关键的区别——可以合理地 不喜欢 这种区别,但是 忽略 很明显,这是完全错误的。

    python语句是python编译器必须特别注意的事情——它们可能改变名称的绑定,可能改变控制流,和/或可能需要在某些条件下从生成的字节码中完全删除(后者适用于 assert ) print 只有 python 2中这个断言的异常;通过从语句列表中删除它,python 3删除了一个异常,使一般的断言“只是保留”,因此是一种更常规的语言。 特殊情况不足以打破规则 长期以来一直是蟒蛇的信条 import this 在一个交互式翻译公司 >>> 提示查看显示的“python的禅”,而对语言的这种更改消除了由于早期错误的设计决策而必须保留多年的违反这一原则的情况。

    对于初学者来说,操作员打印可以 不属于一般应用 逻辑。对他们来说,这是神秘的 运算符,它是 他们的计划。他们希望它看起来 不同的。

    尽早治愈初学者的误解是一件很好的事情。

    所有的初学者的书 现在介绍基本的python 2.x 保证从拳头上摔下来 例子。当然可以,语言 有时会改变,但改变是 通常新手看不见。

    语言很少会发生深刻的和向后的不兼容的变化(大约每十年有一次是由python完成的),而且很少有语言特性“对新手来说是非常明显的”,所以观察的总数很小——但即使在这个小罗盘中,我们也很容易找到反例,在这个罗盘中,初学者非常明显的特性设计得非常糟糕。移除它是值得的。例如,现代的BASIC方言,如微软的Visual Basic,不使用用户输入的显式行号,这是一个“功能”,对每个人来说都是可怕的,而且非常明显,因为它在BASIC的早期方言中是强制性的。Lisp的现代变体(从方案开始)不使用动态范围界定,这是一种对初学者来说非常明显(通常表现为难以理解代码中的错误)的错误功能,基本上只要他们开始在Lisp 1.5中编写函数(我曾经是这方面的初学者,并且可以证明它对我有多么不利)。

    对我来说不是很明显 打印功能可以 在应用程序级别上重复。 例如,有时我想 将控制台上的打印重定向为 模式操作系统对话框。

    不确定我是否遵循这个“要点”。只是改变 sys.stdout 到你最喜欢的伪文件对象并重定向到你心脏的内容——你有 选项 猴子修补内置功能 打印 (你在Python2中从来没有这样做过),但是没有人会扭动你的手臂强迫你这样做。

    人们说很难重写 所有打印语句到函数, 他们强迫每一条蟒蛇2.x 开发人员要为所有人做到这一点 他们的项目。很好,不难 带自动转换器。

    这个 2to3 工具确实可以处理所有这些容易出现的表面不兼容问题——没有汗液(而且它还需要运行来处理更多的问题 打印 ,所以人们确实广泛使用它)。那么,你的“重点”是什么?

    喜欢有能力的人 操作函数打印将 如果印刷品是 语句包装函数 打印 .

    这种安排本身不会删除不必要的关键字(尤其是不合理的 不规则性 ,正如我上面解释的:一个声明 很好的理由 一个语句,因为编译器完全不需要以任何方式、形状或形式特别注意它!).我还不清楚拥有这样一个底层函数会增加任何实际的价值,但是如果你有实际的用例,你当然可以在python-ideas邮件列表中提出这个例子,这样一个底层函数,如果被证明是宝贵的,可以被 打印 python 2.7中的语句以及 打印 在python 3.2中的函数。

    然而,考虑一个典型的情况,在这种情况下,人们可能希望对内置的 打印 :添加关键字参数以允许特殊调整。怎么会 __print__ 你显然是被提议的函数,从 阿-普林特 声明?比恐怖的 >> myfile 后面的逗号…?用! 打印 作为函数,关键字参数只遵循适用于 每一个 函数和函数调用——极乐!

    所以,总的来说,它更适合 打印 作为一个函数,因为它消除了异常、特殊情况和任何对异常语法的需要——简单、规则和一致性是Python的商标。

        2
  •  11
  •   SingleNegationElimination    15 年前

    这就是我讨厌2.x中的打印声明的原因。

    >>> something()
    <something instance at 0xdeadbeef>
    >>> print something()
    <something instance at 0xdeadbeef>
    

    无用的对象没有用处 __str__ 好吧,我可以处理,再看一看。

    >>> dir(something())
    ['foo', 'bar', 'baz', 'wonderful']
    >>> help(something().foo)
    "foo(self, callable)"
    

    隐马尔可夫模型。。那么,这个可调用函数是否需要参数?

    >>> something().foo(print)
        something().foo(print)
                            ^
    SyntaxError: invalid syntax
    >>> something().foo(lambda *args: print(*args))
        something().foo(lambda *args: print(*args))
                                          ^
    SyntaxError: invalid syntax
    

    所以…我必须定义一个要使用的函数

    >>> def myPrint(*args): print *args
        def myPrint(*args): print *args
                                  ^
    SyntaxError: invalid syntax
    >>> def myPrint(*args): print args
    ...
    >>> myPrint(1)
    (1,)
    

    颤抖或使用 sys.stdout.write 因为它的行为与 print . 它也 不同,这意味着我几乎永远不会记得它的存在。

    使用 打印 在一个简短的一次性工具中的语句,然后将其改进为使用日志记录或更好的工具,这是不雅的。如果打印像这些东西一样工作,特别是可以与高阶函数一起使用,那么它将比不使用时使用的东西更好。 真实的 测井或 真实的 调试器。

        3
  •  8
  •   Greg Hewgill    15 年前

    这个 print 声明中也带有不寻常的 >> 打印到特定文件的语法。在Python中没有其他语句具有这种语法,因此这种方式很少见。

    不过,我相信你是对的,大部分问题 打印 通过引入 __print__ 功能。

        4
  •  6
  •   Jacob    15 年前

    我发现gvr的“打印是唯一一个应用程序级功能,它有一个专门的声明”令人信服。python是一种通用语言,不应该有一个以操作符或关键字的形式输出到流的语句。

        5
  •  3
  •   Aiden Bell    15 年前

    它不是pythonic,因为语法应该是:

    stdout.append("Hello World")
    

    stdout += "hello world"
    

    免责声明:我真的很喜欢蟒蛇。

    严肃地说…

    我认为python的对象模型和“自己实现”的方法对于属性可见性之类的事情是很好的。我认为这种“一切都是对象”的OOP方法,甚至定义为对象集合结构的对象也非常清晰。

    我担心python会做的是成为一种不以清晰的方式呈现其意图的语言…我不想看到这些原则的美妙之处被过分考虑已经非常规的语法表达所束缚。有点像 Lisp 结构上很美,语法上很严肃。