别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

    • PEP 中文翻译计划
    • [译] PEP-8 -- 编码风格指南中文版✨✨
    • [译] PEP202--列表推导式
    • [译] PEP 255--简单的生成器
    • [译] PEP 285--添加一种布尔类型
    • [译] PEP 318--函数和方法的装饰器
    • [译] PEP 328--导入多行及绝对/相对
    • [译]pep 333 -- Python Web 服务器网关接口 v1.0
    • [译]PEP 342--增强型生成器——协程
    • [译]PEP 380--子生成器的语法
    • [译]PEP 484 -- 类型提示
    • [译] PEP 525--异步生成器
    • [译] PEP 530--异步推导式
    • [译] PEP614--放宽对装饰器的语法限制
    • [译] PEP-312--Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性
    • [译]PEP 3099--Python 3 中不会改变的事情
    • [译] PEP 3105--改 print 为函数
    • [译]PEP 3107 -- 函数注解
    • [译]PEP-3129 类装饰器
    • [译] PEP 3155--类和方法的特定名称
      • 原理
      • 提议
      • 嵌套类的示例
      • 嵌套函数的示例
      • 不足之处
      • 讨论
        • 去除模块名称
        • 恢复 unbound 方法
      • 命名的选择
      • 相关链接
      • 版权
    • [译]pep 3333 -- Python Web 服务器网关接口 v1.0.1
  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • PEP
佚名
2019-11-27
目录

[译] PEP 3155--类和方法的特定名称

PEP 原文 : https://www.python.org/dev/peps/pep-3155/ (opens new window)

PEP 标题: PEP 3155 -- Qualified name for classes and functions

PEP 作者: Antoine Pitrou

创建日期: 2011-10-29

合入版本: 3.3

译者 :豌豆花下猫@Python 猫公众号

PEP 翻译计划 :https://github.com/chinesehuazhou/peps-cn

# 原理

一直以来,对于嵌套类的自省,Python 的支持很不够。给定一个类对象,根本不可能知道它是在某个类中定义的,还是在顶层模块中定义的;而且,如果是前者,也不可能知道它具体是在哪个类中定义的。虽然嵌套类通常被认为是不太好的用法,但这不应该成为不支持内层自省的理由。

Python 3 因为丢弃了以前的未绑定方法(unbound method),而受到了侮辱性的伤害。

在 Python 2 中,给出以下定义:

class C:
    def f():
        pass
1
2
3

你可以从C.f 对象中获得其所属的类:

>>> C.f.im_class
<class '__main__.C'>
1
2

这种用法在 Python 3 中已经没有了:

>>> C.f.im_class
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'im_class'
>>> dir(C.f)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__get__', '__getattribute__',
'__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__',
'__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__']
1
2
3
4
5
6
7
8
9
10
11
12

这就限制了用户可以使用的自省能力。当将程序移植到 Python 3 时,它可能会产生一些实际的问题,例如在 Twisted 的核心代码中,就多次使用到了这种自省方法。此外,这还限制了对 pickle 序列化的支持 (opens new window) [1]。

# 提议

本 PEP 提议在函数和类中添加 __qualname__ 属性。

对于顶层的函数和类,__qualname__ 属性等于__name__ 属性。对于嵌套的类、方法和嵌套函数,__qualname__ 属性包含一个点式路径(dotted path),通向顶层模块下的对象。函数的局部命名空间在点式路径中由名为 <locals> 的组件表示。

函数和类的 repr() 和 str() 被修改为使用__qualname__ 而不再是__name__。

# 嵌套类的示例

>>> class C:
...   def f(): pass
...   class D:
...     def g(): pass
...
>>> C.__qualname__
'C'
>>> C.f.__qualname__
'C.f'
>>> C.D.__qualname__
'C.D'
>>> C.D.g.__qualname__
'C.D.g'
1
2
3
4
5
6
7
8
9
10
11
12
13

# 嵌套函数的示例

>>> def f():
...   def g(): pass
...   return g
...
>>> f.__qualname__
'f'
>>> f().__qualname__
'f.<locals>.g'
1
2
3
4
5
6
7
8

# 不足之处

对于嵌套函数(以及在函数内部定义的类),由于无法从外部获得函数的命名空间,因此点式路径无法以动态编程的方式遍历。相比于空的__name__,它对于人类读者还是有些帮助的。

跟__name__属性一样,__qualname__ 属性是静态计算的,不会自动地重新绑定。

# 讨论

# 去除模块名称

跟__name__一样,__ qualname__ 不包含模块的名称。这使得它不受制于模块别名和重新绑定,也得以在编译期进行计算。

# 恢复 unbound 方法

恢复 unbound 方法只能解决此 PEP 解决了的部分问题,而且代价更高(额外的对象类型和额外的间接寻址,不如用额外的属性)。

# 命名的选择

简而言之,“Qualified name”是新加属性的最佳表达。(译注:不知道如何准确翻译此处的 Qualified?)

它不是“full name”或“fully qualified name”,因为它(故意)不包括模块的名称。将其称为“path”,则可能会与文件系统的路径及__file__属性混淆。

关于这个属性的名称,最初的建议是将其命名为__qname__,但是许多人却认为它晦涩难懂(他们不知道这个术语已有先例,例如用在了 XML 规范[2]中),这就是为什么这个稍微长点但更明确的__qualname__ 会被选中的原因。

# 相关链接

[1] "pickle should support methods": http://bugs.python.org/issue9276

[2] "QName" 在 Wikipedia 的解释: http://en.wikipedia.org/wiki/QName

# 版权

本文档已进入公共领域。

源文档: https://github.com/python/peps/blob/master/pep-3155.txt (opens new window)

编辑 (opens new window)
#类
上次更新: 2024-07-15, 08:03:22
[译]PEP-3129 类装饰器
[译]pep 3333 -- Python Web 服务器网关接口 v1.0.1

← [译]PEP-3129 类装饰器 [译]pep 3333 -- Python Web 服务器网关接口 v1.0.1→

最近更新
01
提升沟通亲和力的实用策略
03-26
02
工作
07-15
03
如何选房子
06-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式