如何找出python中的特定方法是"in-place"还是不是?
How to find out a specific method in python is "in-place" or not?
我找不到区分就地方法和python中的可分配方法的方便方法。
我的意思是,例如像 my_list.sort()
这样的方法不需要赋值,它会自行改变(它是 就地 对吗?),但其他一些方法需要赋值给多变的。
我错了吗?
您无法轻易找到这种区别的原因是,除非按照脆弱的约定,否则它实际上并不存在。 “就地”仅意味着函数修改可变参数的数据,而不是 returning 一个全新的对象。如果“非就地”被认为是一个函数 return 是一个封装更新数据的新对象,单独留下输入,那么有太多其他可能的约定值得编目。
没有return一个值的standard library does its best to follow the convention of not returning values from single-argument in-place functions. So for example you have list.sort
, list.append
, random.shuffle
and heapq.heapify
all operate in-place, returning None
. At the same time, you have functions and methods that create new objects, and must therefore return them, like sorted
, list.__add__
and tuple.__iadd__
. But you also have in-place methods that must return a value like list.__iadd__
(compare to list.extend
。
__iadd__
和类似的就地运算符强调了一个非常重要的点,即就地运算不是不可变对象的选项。 Python 有一个解决方法:
x = (1, 2)
y = (3, 4)
x += y
对于所有对象,第三行相当于
x = type(x).__iadd__(x, y)
忽略该方法作为函数调用的事实,请注意名称 x
已重新分配,因此即使 x += y
必须创建一个新对象(例如,因为 tuple
是不可变的),你仍然可以通过名称x
看到它。在这种情况下,可变对象通常只是 return x
,因此方法调用将 出现 而不是 return 一个值,即使它确实如此.
有趣的是,重新分配有时会导致意外错误:
>>> z = ([],)
>>> z[0].extend([1, 2]) # OK
>>> z[0] += [3, 4] # Error! But list is mutable!
很多第三方库,例如numpy, support the convention of in-place functions without a return value, up to a point. Most numpy functions create new objects, like np.cumsum
, np.add
, and np.sort
. However, there are in also functions and methods that operate in-place and return None
, like np.ndarray.sort
and np.random.shuffle
。
numpy 可以使用大内存缓冲区,这意味着通常需要就地操作。 一些函数和方法(最值得注意的是通用函数)没有一个单独的就地版本的函数,而是有一个可以设置为输入的out
参数,比如np.cumsum
, np.ndarray.cumsum
, and np.add
。在这些情况下,该函数将就地运行,但仍然 return 对 out
参数的引用,与 python 的就地运算符的方式非常相似。
更复杂的是,并非所有函数和方法都对单个对象执行单个操作。你可以这样写一个class来说明:
class Test:
def __init__(self, value):
self.value = value
def op(self, other):
other.value += self.value
return self
此 class 修改了另一个对象,但 return 引用了未修改的 self
。虽然人为设计,但该示例用于说明 in-place/not-in-place 范式并非无所不包。
TL;DR
最后,in-place 的一般概念通常很有用,但不能取代阅读文档和了解每个函数在单独基础上的作用的需要。这也将使您免于许多常见的陷阱,可变对象支持就地操作,而不可变对象只是模拟它们。
我找不到区分就地方法和python中的可分配方法的方便方法。
我的意思是,例如像 my_list.sort()
这样的方法不需要赋值,它会自行改变(它是 就地 对吗?),但其他一些方法需要赋值给多变的。
我错了吗?
您无法轻易找到这种区别的原因是,除非按照脆弱的约定,否则它实际上并不存在。 “就地”仅意味着函数修改可变参数的数据,而不是 returning 一个全新的对象。如果“非就地”被认为是一个函数 return 是一个封装更新数据的新对象,单独留下输入,那么有太多其他可能的约定值得编目。
没有return一个值的standard library does its best to follow the convention of not returning values from single-argument in-place functions. So for example you have list.sort
, list.append
, random.shuffle
and heapq.heapify
all operate in-place, returning None
. At the same time, you have functions and methods that create new objects, and must therefore return them, like sorted
, list.__add__
and tuple.__iadd__
. But you also have in-place methods that must return a value like list.__iadd__
(compare to list.extend
。
__iadd__
和类似的就地运算符强调了一个非常重要的点,即就地运算不是不可变对象的选项。 Python 有一个解决方法:
x = (1, 2)
y = (3, 4)
x += y
对于所有对象,第三行相当于
x = type(x).__iadd__(x, y)
忽略该方法作为函数调用的事实,请注意名称 x
已重新分配,因此即使 x += y
必须创建一个新对象(例如,因为 tuple
是不可变的),你仍然可以通过名称x
看到它。在这种情况下,可变对象通常只是 return x
,因此方法调用将 出现 而不是 return 一个值,即使它确实如此.
有趣的是,重新分配有时会导致意外错误:
>>> z = ([],)
>>> z[0].extend([1, 2]) # OK
>>> z[0] += [3, 4] # Error! But list is mutable!
很多第三方库,例如numpy, support the convention of in-place functions without a return value, up to a point. Most numpy functions create new objects, like np.cumsum
, np.add
, and np.sort
. However, there are in also functions and methods that operate in-place and return None
, like np.ndarray.sort
and np.random.shuffle
。
numpy 可以使用大内存缓冲区,这意味着通常需要就地操作。 一些函数和方法(最值得注意的是通用函数)没有一个单独的就地版本的函数,而是有一个可以设置为输入的out
参数,比如np.cumsum
, np.ndarray.cumsum
, and np.add
。在这些情况下,该函数将就地运行,但仍然 return 对 out
参数的引用,与 python 的就地运算符的方式非常相似。
更复杂的是,并非所有函数和方法都对单个对象执行单个操作。你可以这样写一个class来说明:
class Test:
def __init__(self, value):
self.value = value
def op(self, other):
other.value += self.value
return self
此 class 修改了另一个对象,但 return 引用了未修改的 self
。虽然人为设计,但该示例用于说明 in-place/not-in-place 范式并非无所不包。
TL;DR
最后,in-place 的一般概念通常很有用,但不能取代阅读文档和了解每个函数在单独基础上的作用的需要。这也将使您免于许多常见的陷阱,可变对象支持就地操作,而不可变对象只是模拟它们。