为什么Python有格式化函数和格式化方法

2024-04-06

The format http://docs.python.org/2/library/functions.html#format内置函数中的函数似乎是str.format http://docs.python.org/2/library/stdtypes.html#str.format专门用于格式化单个对象的方法。

eg.

>>> format(13, 'x')
'd'

显然优于

>>> '{0:x}'.format(13)
'd'

在我看来,它确实看起来更好,但为什么不直接使用str.format在任何情况下都让事情变得更简单?这两者均已在2.6所以必须有一个充分的理由同时拥有这两者,它是什么?

Edit:我问的是str.format and format,这不是我们没有的原因(13).format


tldr; format只是打电话obj.__format__并被使用str.format方法可以做更高层次的事情。对于较低级别来说,教导对象如何格式化自身是有意义的。

它只是语法糖

事实上,该函数与以下函数共享名称和格式规范:str.format可能会产生误导。的存在str.format很容易解释:它进行复杂的字符串插值(替换旧的%操作员);format可以将单个对象格式化为字符串,即最小的子集str.format规格。那么,为什么我们需要format?

The format函数是一个替代obj.format('fmt')在一些结构中发现OO https://en.wikipedia.org/wiki/Object-oriented_programming语言。这一决定与该决定的理由是一致的len(关于为什么Python使用函数len(x)而不是财产x.length like JavaScript https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/length或红宝石)。

当一种语言采用obj.format('fmt')构造(或obj.length, obj.toString等等),类被阻止拥有名为format (or length, toString,你明白了) - 否则它会影响语言的标准方法。在这种情况下,语言设计者将防止名称冲突的负担交给了程序员。

Python非常喜欢PoLA http://en.wikipedia.org/wiki/Principle_of_least_astonishment并通过了__dunder__(双下划线)内置函数约定,以尽量减少用户定义的属性和语言内置函数之间发生冲突的可能性。所以obj.format('fmt')变成obj.__format__('fmt'),当然你可以打电话obj.__format__('fmt')代替format(obj, 'fmt')(同样的方式你可以打电话obj.__len__()代替len(obj)).

使用你的例子:

>>> '{0:x}'.format(13)
'd'
>>> (13).__format__('x')
'd'
>>> format(13, 'x')
'd'

哪一个更干净、更容易打字? Python的设计非常务实,不仅干净而且与Python的风格非常契合鸭型 http://en.wikipedia.org/wiki/Duck_typing接近OO https://en.wikipedia.org/wiki/Object-oriented_programming并让语言设计者可以自由地更改/扩展底层实现,而不会破坏遗留代码。

The PEP 3101 http://www.python.org/dev/peps/pep-3101/推出了新的str.format方法和format内置,没有任何理由的评论format函数,但实现显然只是句法糖 http://en.wikipedia.org/wiki/Syntactic_sugar:

def format(value, format_spec):
    return value.__format__(format_spec)

我的观点就在这里。

Guido 对此有何评论(或者是官方的?)

引用非常BDFL http://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life about len:

首先我选择的是len(x) over x.len() for HCI https://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction原因(def __len__()来得很晚)。实际上有两个相互交织的原因HCI https://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction:

(a) 对于某些运算,前缀表示法读起来比后缀更好——前缀(和中缀!)运算在数学中有着悠久的传统,它喜欢视觉帮助数学家思考问题的符号。比较一下我们重写公式的简单性,例如x*(a+b) into x*a + x*b使用原始的 OO 表示法做同样的事情是很笨拙的。

(b) 当我读到这样的代码时len(x)我知道它在询问某物的长度。这告诉我两件事:结果是一个整数,参数是某种容器。相反,当我读到x.len(),我必须已经知道x是某种实现接口或继承自具有标准的类的容器len()。见证一下当一个没有实现映射的类有一个映射时我们偶尔会遇到的混乱get() or keys()方法,或者不是文件的东西有write() method.

用另一种方式说同样的事情,我明白了‘len' 作为内置操作。我不想失去它。 /…/

source: [电子邮件受保护] http://effbot.org/pyfaq/why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list.htm(原帖here http://mail.python.org/pipermail/python-3000/2006-November/004643.html还有 Guido 正在回答的原始问题)。Abarnert https://stackoverflow.com/users/908494/abarnert还建议:

还有关于 len 的额外推理设计和历史常见问题解答 http://docs.python.org/2/faq/design.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list。尽管它不是那么完整或那么好的答案,但它无疑是官方的。 –abarnert https://stackoverflow.com/users/908494/abarnert

这是一个实际问题还是只是语法挑剔?

对于像 Python 这样的语言来说,这是一个非常实际和现实的问题,Ruby https://groups.google.com/forum/?fromgroups#!topic/rubymotion/kiQTDaMY7As或 Javascript,因为在动态类型语言中,任何可变对象实际上都是命名空间,并且私有方法或属性的概念是约定问题。可能我无法说得比abarnert https://stackoverflow.com/users/908494/abarnert在他的评论中:

另外,就 Ruby 和 JS 的命名空间污染问题而言,值得指出的是,这是动态类型语言的固有问题。在 Haskell 和 C++ 等各种静态类型语言中,特定于类型的自由函数不仅是可能的,而且是惯用的。 (参见接口原理 http://www.gotw.ca/publications/mill02.htm.) 但在 Ruby、JS 和 Python 等动态类型语言中,自由函数必须是通用的。动态语言的语言/库设计的一个重要部分是选择正确的此类函数集。

例如,我刚刚离开Ember.js http://emberjs.com/有利于Angular.js http://angularjs.org/因为我厌倦了 Ember 中的命名空间冲突 https://stackoverflow.com/questions/16515900/reserved-atribute-names-in-ember-js-models; Angular 使用一种优雅的类似 Python 的策略来处理这个问题,即为内置方法添加前缀(使用$thing在 Angular 中,而不是像 python 那样的下划线),因此它们不会与用户定义的方法和属性冲突。是的,整个__thing__不是特别漂亮,但我很高兴 Python 采用了这种方法,因为它非常明确并且避免了PoLA http://en.wikipedia.org/wiki/Principle_of_least_astonishment有关对象命名空间冲突的错误类别。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么Python有格式化函数和格式化方法 的相关文章

  • 不要在异常堆栈中显示 Python raise-line

    当我在 Python 库中引发自己的异常时 异常堆栈将引发行本身显示为堆栈的最后一项 这显然不是一个错误 在概念上是正确的 但是当您在外部使用代码 例如作为模块 时 它会将重点放在对调试无用的东西上 有没有办法避免这种情况并强制 Pytho
  • 如何在 for 循环中跳过一些迭代

    在 python 中 我通常简单地循环遍历范围 for i in range 100 do something 但现在我想跳过循环中的几个步骤 更具体地说 我想要类似的东西continue 10 这样它就会跳过整个循环并将计数器增加 10
  • Python中的键盘可中断阻塞队列

    It seems import Queue Queue Queue get timeout 10 键盘可中断 ctrl c 而 import Queue Queue Queue get 不是 我总是可以创建一个循环 import Queue
  • 如何在Python中通过URL下载Azure Blob存储文件?

    我正在尝试从我的存储帐户下载 Azure Blob 存储文件 为此 我检查了 URL 是什么 并且正在执行以下操作 with urllib request urlopen
  • python 正则表达式中括号的奇怪行为

    我正在编写一个 python 正则表达式 它可以在文本文档中查找引用的字符串 从黑匣子中记录的航空公司飞行员的引用 我首先尝试编写具有以下规则的正则表达式 返回引号之间的内容 如果以 single 打开 则仅在以 single 关闭时返回
  • 为什么我在 Python 中收到“连接被拒绝”错误? (插座)

    我是套接字新手 请原谅我完全缺乏理解 我有一个服务器脚本 server py usr bin python import socket import the socket module s socket socket Create a so
  • 如何从 python 脚本更改 python 文件中的变量值

    我目前有一个 python 文件 其中包含一堆带有值的全局变量 我想从一个单独的 python 脚本永久更改这些值 我尝试过 setattr 等 但似乎不起作用 有没有办法做到这一点 简短的回答是 不 不值得这么麻烦 听起来您正在尝试创建一
  • 如何在 Python 中重命名文件并保留创建日期

    我知道创建日期不存储在文件系统本身中 但是当我使用时我遇到了问题os rename 它正在更新我正在使用的文件的创建日期 是否可以重命名文件而不更改其原始创建日期 正如都铎所说 你可以使用os stat http docs python o
  • 没有名为 objc 的模块

    我正在尝试将 cocoa python 与 Xcode 一起使用 但它总是会出现错误 Traceback most recent call last File main py line 10 in
  • 在 Django 1.9 中使用信号

    在 Django 1 8 中 我能够使用信号执行以下操作 一切顺利 init py from signals import 信号 py receiver pre save sender Comment def process hashtag
  • 使用 pymongo 查询空字段

    我想使用 python 查询 mongo 中的空字段 但是它很难处理单词 null 或 false 它要么给我错误 它们在 python 中未定义 要么在 mongo 中搜索字符串 null 和 false 这两种情况我都不希望发生 col
  • 结束一天(日期时间)的最优雅的方式是什么?

    我目前正在编写一些报告代码 允许用户选择指定日期范围 它的工作方式 简化 是 用户 可选 指定年份 用户 可选 指定月份 用户 可选 指定一天 这是一个代码片段 以及描述我想要的内容的注释like to do from datetime i
  • 嵌套 for 循环以列出具有不同“if”条件的理解

    我正在尝试将此嵌套循环转换为列表理解 但我不确定是否可能 因为 tmp 列表中的项目可能有不同的值 这是最好的方法吗 谢谢 final for a in range 13 1 for b in range 0 4 for c in rang
  • Scrapy文件下载如何使用自定义文件名

    For my scrapy http doc scrapy org index html我目前正在使用的项目文件管道 https doc scrapy org en latest topics media pipeline html scr
  • 尝试输入字符串时出现名称错误[重复]

    这个问题在这里已经有答案了 import pickle import os import time class Person def init self number address self number number self addr
  • 帮助我在 Python 中实现反向传播

    EDIT2 新的训练集 Inputs 0 0 0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 1 0 0 0 1 0 1 0 1 0 2 0 1 0 3 0 1 0 4 0 2 0 0 0 2 0 1 0 2 0 2
  • 如何加速Python循环

    我查看了几个网站上的一些讨论 但没有一个给我解决方案 这段代码运行时间超过5秒 for i in xrange 100000000 pass 我正在研究整数优化问题 我必须使用O n log n 算法编辑 O n 4 算法 其中n代表矩阵的
  • 保存 Jupyter Notebook,并显示 Plotly Express 小部件

    我有一个 Jupyter 笔记本 python 我使用plotlyexpress 在笔记本中绘图以进行分析 我想与非编码人员共享此笔记本 并让交互式视觉效果仍然可用 但它似乎不起作用 我尝试以下此处提出的建议 https community
  • jupyter run magic 将参数传递给笔记本

    当您在第一个 jupyter 笔记本 first ipynb 中时 您可以执行第二个 但如何传递参数呢 假设第二个有以下内容 xx 10 您可以从第一个调用第二个 如下所示 run second ipynb xx will print 10
  • Python list.extend() 是保序的吗?

    我想知道扩展函数是否保留两个列表中的顺序 gt gt list 1 2 3 gt gt list extend 4 5 gt gt list 1 2 3 4 5 扩展总是这样工作吗 Yes list extend just extends给

随机推荐