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