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