为了账号安全,请及时绑定邮箱和手机立即绑定

您如何预先知道某个方法(或函数)在调用时是否会更改变量?

您如何预先知道某个方法(或函数)在调用时是否会更改变量?

白猪掌柜的 2021-05-30 00:04:06
我是 R 的 Python 新手。我最近花了很多时间阅读 Python 中的一切如何都是对象,对象可以调用自己的方法,方法是类中的函数,yada yada yada。这是我不明白的。采取以下简单的代码:mylist = [3, 1, 7]如果我想知道数字 7 出现了多少次,我可以这样做:mylist.count(7)那当然返回 1。如果我想将计数值保存到另一个变量:seven_counts = mylist.count(7)到现在为止还挺好。除了语法之外,行为类似于 R。但是,假设我正在考虑在我的列表中添加一个数字:mylist.append(9)等一下,该方法实际上改变了变量本身!(即,“mylist”已被更改,现在将数字 9 作为列表中的第四个数字。)将代码分配给一个新变量(就像我对 Seven_counts 所做的那样)会产生垃圾:newlist = mylist.append(9)我发现这种行为的不一致有点奇怪,并且坦率地说是不可取的。(假设我想先看看 append 的结果是什么样的,然后可以选择决定是否要将它分配给一个新变量。)我的问题很简单:有没有办法提前知道调用特定方法是否会实际改变您的变量(对象)?
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

只需查看文档:


>>> list.count.__doc__

'L.count(value) -> integer -- return number of occurrences of value'

>>> list.append.__doc__

'L.append(object) -> None -- append object to end'

确实没有一种简单的方法可以告诉您,但是:


不可变对象 --> 无法通过方法调用进行更改


因此,例如,tuple没有影响元组的方法,因为它是不可更改的,因此方法只能返回新实例。


而且,如果您“想先看看追加结果如何,然后可以选择是否将其分配给新变量”,则可以将列表与一个具有一个元素的新列表连接起来。


IE


>>> l = [1,2,3]

>>> k = l + [4]

>>> l

[1, 2, 3]

>>> k

[1, 2, 3, 4]


查看完整回答
反对 回复 2021-06-01
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

除了阅读文档(对于某些方法,该方法将包括用于指定返回值的类型注释)或在交互式解释器中使用该方法(包括help()用于检查文档字符串中的类型注释)之外,不,您不能预先知道只是看方法。

也就是说,您看到的行为是故意的。Python方法要么返回一个的对象的经修改的拷贝修改代替对象; 在内置插件中最不重要的,他们从来没有做到既(的一些方法变异的对象,并返回一个非None数值,但它从来都只是突变的对象;pop的方法dict,并list为这种情况的一个例子)。

这种或/或行为是故意的;如果他们不遵守该规则,那么您将面临一个更加混乱且难以识别的问题,即确定是append对它所调用的值进行了更改还是返回了一个新对象。您肯定会回来的list,但是它是新的list还是一样的list?如果它改变了它被调用的值,那么

newlist = mylist.append(9)

有点奇怪;newlist并且mylist是相同的别名list(所以为什么要同时使用两个名称?)。您可能暂时不会注意到;您将继续使用newlist,以为它独立于mylist,而只是查看mylist并发现它们全都被弄乱了。通过返回所有此类“就地修改”方法None(或至少不返回原始对象),可以更快/更轻松地发现错误;如果您尝试使用newlist,错误地认为它是 a list,您将立即得到TypeErrors 或AttributeErrors。

基本上,提前知道的唯一方法是阅读文档。对于名称表示修改操作的方法,您可以检查返回值,并经常了解它们是否正在变异。它有助于首先了解哪些类型是可变的;listdictset并且bytearray都是可变的,他们有自己的不可变(除了方法dict,它没有一成不变的副本)缺乏往往会发生变异的对象到位。

缺省趋向于仅仅因为更有效而使对象在适当位置突变。如果你有一个 100,000 element list,它的默认行为append会创建一个新的 100,001 元素list并返回它会非常低效(并且没有明显的方法可以避免它)。对于不可变类型(例如strtuplefrozenset),这是不可避免的,如果您想保证对象永远不会就地发生变异,您可以使用这些类型,但这样做的代价是不必要的创建和销毁对象会减慢您的速度大多数情况下的代码。


查看完整回答
反对 回复 2021-06-01
?
GCT1015

TA贡献1827条经验 获得超4个赞

只需查看文档:


>>> list.count.__doc__

'L.count(value) -> integer -- return number of occurrences of value'

>>> list.append.__doc__

'L.append(object) -> None -- append object to end'

确实没有一种简单的方法可以告诉您,但是:


不可变对象 --> 无法通过方法调用进行更改


因此,例如,tuple没有影响元组的方法,因为它是不可更改的,因此方法只能返回新实例。


而且,如果您“想先看看追加结果如何,然后可以选择是否将其分配给新变量”,则可以将列表与一个具有一个元素的新列表连接起来。


IE


>>> l = [1,2,3]

>>> k = l + [4]

>>> l

[1, 2, 3]

>>> k

[1, 2, 3, 4]


查看完整回答
反对 回复 2021-06-01
  • 3 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信