Python:如何检查参数的类型是通过值传递还是通过引用传递?

2024-05-23 18:11:42 发布

您现在位置:Python中文网/ 问答频道 /正文

似乎原子类型(int、string,…)是通过值传递的,而所有其他类型(对象、函数指针、方法指针等等)都是通过引用传递的。在

检查变量是通过值传递还是通过引用传递的最好方法是什么?在

isinstance(input_, float) or isinstance(input_, basestring) or <...>

看起来很不雅观。在

我需要它的原因如下:我有一个类wx.按钮,如果arg/kwarg是按值传递的类型,则将不考虑在其他对象中更新其值。所以一些支票是有益的

^{pr2}$

Tags: or对象方法类型inputstring原因float
2条回答

这个问题没有出现。所有都以完全相同的方式传递,无论类型、值、操作系统、月相等等

这种类型的参数传递是否最好地描述为按值传递、按引用传递还是其他方式,有待商榷(不过请注意,使用“传递值/引用”需要“值”/“引用”的非标准定义,这是“传递对象”等其他术语的主要理由)。这里没关系。总是一样的。在

编辑:在您的示例中,handler的语义不会根据参数类型而改变。其中一个被分配给变量(又称名称):

def my_handler(x):
    x = <whatever>

。。。但是my_handler(<anything>)不会改变参数所指的对象(如果传入局部变量、对象属性、更复杂表达式的结果或其他任何内容,也无所谓)。顺便说一句,所有东西都是一个对象,你的人为区分(“原子”、“指向函数的指针”)毫无意义。在

或者,函数(尝试)更改对象的值(例如,向集合添加/删除项、更改对象属性、调用更改可间接观察到的某些状态的方法)。如果对象不支持它(例如调用一个不存在的方法),这可能会引发异常,但这发生在任何访问中,而不仅仅是变异。如果对象的值确实发生了更改,则通过对该对象的引用,始终可见。由于对现有对象的新引用是在许多情况下创建的(例如参数传递、变量赋值、属性赋值等),您可以通过在一个位置更改其值并在另一个位置观察更改来观察对象没有被复制。这对所有对象都适用(同样,前提是您可以更改对象的值)。在

现在,有些对象是不可变的,这(根据定义)意味着您不能更改它们的值,因此不能以这种方式观察对象“共享”(您可以用其他方式观察它)。这并不意味着赋值根据可变性有不同的语义(事实并非如此),它只是意味着你可以用可变对象做一些你不能用不变对象做的事情。您可以对这两个对象执行的操作对两者都是相同的。在

如果您确实需要更改传递给您的变量的值,可以将其包装在数组中,以便在过程中实现按引用传递:

def increaseInt(i_var):
  i_var[0] += 1

i_ref = [42]
increase(i_ref)
print i_ref[0]  # will print 43

在某些情况下,这可能是解决像你这样的问题的(棘手的)解决办法。在

但一般来说,在Python中,所有的值都是通过引用传递的(在这种意义上,没有创建副本);有些值是不可变的(比如int、string、tuples等等)。给参数变量分配一个新值可能会使您感到困惑-这肯定不会改变之前参数变量中的值,它只是用一个新值覆盖它(从而删除对原始值的附加引用)。这就是为什么上面的例子没有给i_var赋值,而是给i_var[0]赋值。在

相关问题 更多 >