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

Yul*_*a V -1 python types pass-by-reference pass-by-value

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

检查变量是按值传递还是按引用传递的最佳方法是什么?

isinstance(input_, float) or isinstance(input_, basestring) or <...>
Run Code Online (Sandbox Code Playgroud)

似乎非常不优雅.

我需要它的原因如下:我有一个包装wx.Button的类,如果args/kwargs是按值传递的类型,则不会考虑更新其他对象中的值.所以一些检查将是有益的

class PalpyButton(wx.Button):        
    def __init__(self, parent, btnLabel, handler, successMsg = None, args = (), kwargs = {}):
        super(PalpyButton, self).__init__(parent, -1, btnLabel)
        self.handler = handler
        self.successMsg = successMsg
        parent.Bind(wx.EVT_BUTTON, lambda event: self.onClick(event, *args, **kwargs), self)
    def onClick(self, event, *args, **kwargs):
        try:
            self.handler(*args, **kwargs)
            if self.successMsg != None:
                if hasattr(self.successMsg, '__call__'):
                    showInfoMessageBox(self.successMsg())
                else:
                    showInfoMessageBox(self.successMsg)
        except BaseException, detail:
            showErrorMessageBox(detail)
Run Code Online (Sandbox Code Playgroud)

小智 11

问题不会出现.无论类型,价值,操作系统,月相等,一切都以完全相同的方式传递.

这种论证传递方式是否最好被描述为按值传递,通过引用或其他方式进行辩论(尽管请注意,使用"按值传递/引用"需要非标准的"值"/"引用"定义",这是其他术语的主要推理,例如"按对象传递").这没关系.它总是一样的.

编辑:就您的示例而言,语义handler不会根据参数类型而改变.要么分配变量(AKA名称):

def my_handler(x):
    x = <whatever>
Run Code Online (Sandbox Code Playgroud)

...但随后my_handler(<anything>)不会更改参数引用的对象(如果传入局部变量,对象属性,更复杂表达式的结果或其他任何内容,则无关紧要).顺便说一句,一切都是一个对象,你的人为区分("原子","指向函数的指针")毫无意义.

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

现在,一些对象是不可变的,(根据定义)意味着你不能改变它们的值,因此不能以这种方式观察对象"共享"(你可以通过其他方式观察它).这并不意味着赋值具有不同的语义,这取决于可变性(它没有),它只是意味着你可以使用不可变对象做事,而不能用不可变对象做.您可以执行的操作对两者都起作用.