在Python中,当子类化元组时,__new__
使用self作为参数调用该函数.例如,这是PySpark Row
类的一个释义版本:
class Row(tuple): def __new__(self, args): return tuple.__new__(self, args)
但help(tuple)
没有显示出self
参数__new__
:
__new__(*args, **kwargs) from builtins.type Create and return a new object. See help(type) for accurate signature.
并help(type)
说了同样的话:
__new__(*args, **kwargs) Create and return a new object. See help(type) for accurate signature.
那么如何在类定义中self
传递?__new__
Row
是通过*args
吗?
确实__new__
有一些细微之处,其中它的签名可以与情境改变?
或者,文档是否有误?
是否有可能查看源代码,tuple.__new__
以便我可以自己查看答案?
我的问题不是这个问题的重复,因为在那个问题中,所有的讨论都是指__new__
明确拥有self
或cls
作为第一个参数的方法.我想了解一下
为什么该tuple.__new__
方法没有self
或cls
作为第一个参数.
我如何去检查元组类的源代码,看看自己到底发生了什么.
Andrea Corbe.. 11
tuple.__new__
在C中实现的函数和类型通常无法检查,并且它们的签名总是看起来像那个.
正确的签名tuple.__new__
是:
__new__(cls[, sequence])
例如:
>>> tuple.__new__(tuple) () >>> tuple.__new__(tuple, [1, 2, 3]) (1, 2, 3)
毫不奇怪,tuple()
除了你必须重复tuple
两次这一事实之外,这就像打电话一样.
__new__
请注意,第一个参数__new__
始终是类,而不是实例.实际上,角色__new__
是创建并返回新实例.
特殊方法__new__
是静态方法.
我这样说是因为在你Row.__new__
看来我可以看到self
:虽然参数的名称并不重要(除非使用关键字参数),但要注意这self
将是Row
或者是子类Row
,而不是实例.一般惯例是命名第一个参数cls
而不是self
.
那么如何在类定义中
self
传递?__new__
Row
当你打电话时Row(...)
,Python会自动调用Row.__new__(Row, ...)
.
是通过
*args
吗?
你可以写Row.__new__
如下:
class Row(tuple): def __new__(*args, **kwargs): return tuple.__new__(*args, **kwargs)
这有效,并没有错.如果你不关心这些论点,那将非常有用.
确实
__new__
有一些细微之处,其中它的签名可以与情境改变?
不,唯一特别之处__new__
在于它是一种静态方法.
或者,文档是否有误?
我会说它不完整或含糊不清.
为什么该
tuple.__new__
方法没有self
或cls
作为第一个参数.
它确实有,它只是没有出现help(tuple.__new__)
,因为通常该信息不会被C中实现的功能和方法暴露.
我如何去研究
tuple
班级的源代码,亲眼看看自己到底发生了什么.
您要查找的文件是Objects/tupleobject.c
.具体来说,您对该tuple_new()
功能感兴趣:
static char *kwlist[] = {"sequence", 0}; /* ... */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
这"|O:tuple"
意味着:该函数被称为"tuple",它接受一个可选参数(|
分隔可选参数,O
代表Python对象).可以通过关键字参数设置可选参数sequence
.
help(type)
作为参考,您正在查看文档type.__new__
,而您应该在前四行停止help(type)
:
在__new__()
正确签名的情况下签名是type()
:
class type(object) | type(object_or_name, bases, dict) | type(object) -> the object's type | type(name, bases, dict) -> a new type
但这不相关,因为tuple.__new__
签名不同.
super()
!最后但并非最不重要的是,尝试使用super()
而不是tuple.__new__()
直接调用.
tuple.__new__
在C中实现的函数和类型通常无法检查,并且它们的签名总是看起来像那个.
正确的签名tuple.__new__
是:
__new__(cls[, sequence])
例如:
>>> tuple.__new__(tuple) () >>> tuple.__new__(tuple, [1, 2, 3]) (1, 2, 3)
毫不奇怪,tuple()
除了你必须重复tuple
两次这一事实之外,这就像打电话一样.
__new__
请注意,第一个参数__new__
始终是类,而不是实例.实际上,角色__new__
是创建并返回新实例.
特殊方法__new__
是静态方法.
我这样说是因为在你Row.__new__
看来我可以看到self
:虽然参数的名称并不重要(除非使用关键字参数),但要注意这self
将是Row
或者是子类Row
,而不是实例.一般惯例是命名第一个参数cls
而不是self
.
那么如何在类定义中
self
传递?__new__
Row
当你打电话时Row(...)
,Python会自动调用Row.__new__(Row, ...)
.
是通过
*args
吗?
你可以写Row.__new__
如下:
class Row(tuple): def __new__(*args, **kwargs): return tuple.__new__(*args, **kwargs)
这有效,并没有错.如果你不关心这些论点,那将非常有用.
确实
__new__
有一些细微之处,其中它的签名可以与情境改变?
不,唯一特别之处__new__
在于它是一种静态方法.
或者,文档是否有误?
我会说它不完整或含糊不清.
为什么该
tuple.__new__
方法没有self
或cls
作为第一个参数.
它确实有,它只是没有出现help(tuple.__new__)
,因为通常该信息不会被C中实现的功能和方法暴露.
我如何去研究
tuple
班级的源代码,亲眼看看自己到底发生了什么.
您要查找的文件是Objects/tupleobject.c
.具体来说,您对该tuple_new()
功能感兴趣:
static char *kwlist[] = {"sequence", 0}; /* ... */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
这"|O:tuple"
意味着:该函数被称为"tuple",它接受一个可选参数(|
分隔可选参数,O
代表Python对象).可以通过关键字参数设置可选参数sequence
.
help(type)
作为参考,您正在查看文档type.__new__
,而您应该在前四行停止help(type)
:
在__new__()
正确签名的情况下签名是type()
:
class type(object) | type(object_or_name, bases, dict) | type(object) -> the object's type | type(name, bases, dict) -> a new type
但这不相关,因为tuple.__new__
签名不同.
super()
!最后但并非最不重要的是,尝试使用super()
而不是tuple.__new__()
直接调用.