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

Python 增强提案

PEP 542 – 函数头中的点表示法赋值

作者:
Markus Meskanen <markusmeskanen at gmail.com>
状态:
已拒绝
类型:
标准跟踪
创建日期:
2017年2月10日
决议:
Python-Dev 消息

目录

摘要

尽管函数是可赋值的一等公民对象,但函数定义目前只允许使用简单的函数名。

本 PEP 提议通过使用点表示法来分隔对象和函数名,从而支持在函数定义的头部直接将函数赋值给类或实例属性。

虽然有类似的功能,但本 PEP 不涉及对支持赋值的任何内容(如字典键和列表索引)的一般性赋值。

基本原理

目前,如果一个函数需要被赋值给类或实例属性,它需要一个额外的赋值语句。

class MyClass:
    ...

my_instance = MyClass()

def my_function(self):
    ...

# Assign to class attribute
MyClass.my_function = my_function

# Or assign to instance attribute
my_instance.my_function = my_function

这通常不是一个不便之处,但使用点表示法直接在函数头部进行赋值将大大简化这一点。

class MyClass:
    ...

my_instance = MyClass()

# Assign to class attribute
def MyClass.my_function(self):
    ...

# Or assign to instance attribute
def my_instance.my_function(self):
    ...

与标准的类方法相比,使用此功能有多种原因,例如当类在函数头部(如装饰器和类型提示)中被引用时。当实例需要一个回调属性时,这也很有用。

class Menu:
    def __init__(self, items=None, select_callback=None):
        self.items = items if items is not None else []
        self.select_callback = select_callback

my_menu = Menu([item1, item2])

def my_menu.select_callback(item_index, menu):
    print(menu.items[item_index])

而不是

my_menu = Menu([item1, item2])

def select_callback(item_index, menu):
    print(menu.items[item_index])
my_menu.select_callback = select_callback

或者以“不自然”的顺序定义它们

def select_callback(item_index, menu):
    print(menu.items[item_index])

my_menu = Menu([item1, item2], select_callback)

它比“不自然”的方式读起来更好,因为你在函数定义时就已经知道它的用途。它还节省了一行代码,并消除了视觉复杂性。

该功能还可以避免将函数名保留在全局命名空间中。

eggs = 'something'

def Spam.eggs(self):
    ...

def Cheese.eggs(self):
    ...

assert eggs == 'something'

理想情况下,这只会是语法糖。

def x.y():
    ...

# Equals to

def y():
    ...
x.y = y

类似于装饰器是语法糖

@decorate
def f():
    ...

# Equals to

def f():
    ...
f = decorate(f)

实施

__name__ 将遵循普通函数的原则。

class MyClass:
    def my_function1(self):
        ...

def MyClass.my_function2(self):
    ...

assert my_function1.__name__ == 'my_function1'
assert my_function2.__name__ == 'my_function2'

语法将使用 dotted_name 来支持属性的链式调用。

def Person.name.fset(self, value):
    self._name = value

向后兼容性

本PEP完全向后兼容。


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

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