Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 3130 – 访问当前模块/类/函数

作者:
Jim J. Jewett <jimjjewett at gmail.com>
状态:
已拒绝
类型:
标准跟踪
创建日期:
2007 年 4 月 22 日
Python 版本:
3.0
发布历史:
2007 年 4 月 22 日

目录

拒绝通知

此 PEP 已被拒绝。尚不清楚它应该如何实现,或者在边缘情况下应该具有什么样的精确语义,并且没有给出足够重要的用例。回应充其量是冷淡的。

摘要

通常需要对当前模块、类或函数进行引用,但目前没有完全正确的方法来做到这一点。本 PEP 提议添加关键字 __module____class____function__

__module__ 的理由

许多模块会导出各种函数、类和其他对象,但在作为脚本运行时会执行其他活动(例如运行单元测试)。目前的习惯用法是测试模块的名称是否已被设置为一个魔法值。

if __name__ == "__main__": ...

更复杂的内省要求模块(尝试)导入自身。如果导入预期的名称实际上产生了不同的模块,则没有好的解决方法。

# __import__ lets you use a variable, but... it gets more
# complicated if the module is in a package.
__import__(__name__)

# So just go to sys modules... and hope that the module wasn't
# hidden/removed (perhaps for security), that __name__ wasn't
# changed, and definitely hope that no other module with the
# same name is now available.
class X(object):
    pass

import sys
mod = sys.modules[__name__]
mod = sys.modules[X.__class__.__module__]

提议:添加一个 __module__ 关键字,它引用当前正在定义(执行)的模块。(但请参阅待定问题。)

# XXX sys.main is still changing as draft progresses.  May
# really need sys.modules[sys.main]
if __module__ is sys.main:    # assumes PEP (3122), Cannon
    ...

__class__ 的理由

类方法会接收当前实例;由此它们可以确定 self.__class__(对于类方法是 cls)。不幸的是,这个引用是指对象的实际类,它可能是定义类的子类。目前的解决方法是重复类的名称,并假设该名称不会被重新绑定。

class C(B):

    def meth(self):
        super(C, self).meth() # Hope C is never rebound.

class D(C):

    def meth(self):
        # ?!? issubclass(D,C), so it "works":
        super(C, self).meth()

提议:添加一个 __class__ 关键字,它引用当前正在定义(执行)的类。(但请参阅待定问题。)

class C(B):
    def meth(self):
        super(__class__, self).meth()

请注意,通过“New Super”PEP(Spealman)可以进一步简化 super 调用。__class__(或 __this_class__)属性是在尝试简化该 PEP 的解释和/或实现时出现的,但被分离出来作为一个独立决定。

请注意,__class__(或 __this_class__)与绑定 super 对象上的 __thisclass__ 属性不完全相同。现有的 super.__thisclass__ 属性引用方法解析顺序搜索开始的类。在上面的类 D 中,它将引用(名称的当前引用)C。

__function__ 的理由

函数(包括方法)通常希望访问自身,通常是为了私有存储位置或真正的递归。虽然有几种解决方法,但它们都有其缺点。

def counter(_total=[0]):
    # _total shouldn't really appear in the
    # signature at all; the list wrapping and
    # [0] unwrapping obscure the code
    _total[0] += 1
    return _total[0]

@annotate(total=0)
def counter():
    # Assume name counter is never rebound:
    counter.total += 1
    return counter.total

# class exists only to provide storage:
class _wrap(object):

    __total = 0

    def f(self):
        self.__total += 1
        return self.__total

# set module attribute to a bound method:
accum = _wrap().f

# This function calls "factorial", which should be itself --
# but the same programming styles that use heavy recursion
# often have a greater willingness to rebind function names.
def factorial(n):
    return (n * factorial(n-1) if n else 1)

提议:添加一个 __function__ 关键字,它引用当前正在定义(执行)的函数(或方法)。(但请参阅待定问题。)

@annotate(total=0)
def counter():
    # Always refers to this function obj:
    __function__.total += 1
    return __function__.total

def factorial(n):
    return (n * __function__(n-1) if n else 1)

向后兼容性

虽然用户可能已经在使用了这些名称,但双下划线名称(__anything__)明确保留给解释器。因此,在单个功能版本中为这些名称引入特殊含义是可以接受的。

实施

理想情况下,这些名称将是字节码编译器特殊处理的关键字。

Guido 建议 [1] 使用由元类填充的单元格变量。

Michele Simionato 提供了一个使用字节码技巧的原型 [2]。这不需要任何新的字节码运算符;它只是修改了将运行的现有运算符的具体序列。

未解决的问题

  • __module____class____function__ 是正确的名称吗?特别是,名称是否应包含“this”一词,无论是作为 __this_module____this_class____this_function__(在 python-3000 和 python-ideas 列表中讨论的格式)还是作为 __thismodule____thisclass____thisfunction__(受 super.``__thisclass__`` 当前用法启发,但与之冲突)。
  • 这三个关键字是否都需要,还是应将此增强功能限制为对象的子集?方法是否应与其它函数分开处理?

参考资料


来源:https://github.com/python/peps/blob/main/peps/pep-3130.rst

最后修改:2025-02-01 08:59:27 GMT