Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:我可以在可变对象上编写多态交换吗?_Python_Parameter Passing_Pass By Reference_Swap_Mutable - Fatal编程技术网

Python:我可以在可变对象上编写多态交换吗?

Python:我可以在可变对象上编写多态交换吗?,python,parameter-passing,pass-by-reference,swap,mutable,Python,Parameter Passing,Pass By Reference,Swap,Mutable,(目前)缔约国: 对于语言是否支持引用传递语义,有一个简单的“石蕊测试”: 你能用这种语言写一个传统的交换(a,b)方法/函数吗 传统的交换方法或函数接受两个参数并交换它们,以便传递到函数中的变量在函数外部更改 AFAIK,在Python中,不可变对象上的“传统交换函数”是不允许的。但是可变对象呢?出于好奇,我编写了以下测试: # Pythonic way to swap variables (l1, l2) = ([1], [2]) (l1, l2) = (l2, l1) assert (l

(目前)缔约国:

对于语言是否支持引用传递语义,有一个简单的“石蕊测试”:

你能用这种语言写一个传统的交换(a,b)方法/函数吗

传统的交换方法或函数接受两个参数并交换它们,以便传递到函数中的变量在函数外部更改

AFAIK,在Python中,不可变对象上的“传统交换函数”是不允许的。但是可变对象呢?出于好奇,我编写了以下测试:

# Pythonic way to swap variables

(l1, l2) = ([1], [2])
(l1, l2) = (l2, l1)
assert (l1, l2) == ([2], [1])

# This doesn't work inside a function,
# since new bindings are created and discarded

def failed_swap(a, b):
    (a, b) = (b, a)

(l1, l2) = ([1], [2])
failed_swap(l1, l2)
assert (l1, l2) == ([1], [2])

# Working swap function (procedure) on lists

def swap_lists(a, b):
    aux = a[:]
    a[:] = b[:]
    b[:] = aux[:]

(l1, l2) = ([1], [2])
swap_lists(l1, l2)
assert (l1, l2) == ([2], [1])

# The same thing on dicts and sets, thanks to duck typing

def swap_dicts_or_sets(a, b):
    aux = a.copy()
    a.clear()
    a.update(b)
    b.clear()
    b.update(aux)

(s1, s2) = ({1}, {2})
swap_dicts_or_sets(s1, s2)
assert (s1, s2) == ({2}, {1})

(d1, d2) = ({"foo": 1}, {"bar": 2})
swap_dicts_or_sets(d1, d2)
assert (d1, d2) == ({"bar": 2}, {"foo": 1})
所以,我似乎可以在至少一些可变类型上编写一些专门的“传统掉期”

  • 术语:这是否意味着Python支持任何可变对象上的按引用传递语义
  • 如果是这样,我可以编写一个通用的“传统交换”来处理任何可变对象吗

  • 对1的回答类似于“Python总是通过对对象的常量引用来使用传递参数”

    第2个问题的答案是:不,您不能用一般的方法来做,要找到一些反例,假设您想交换树中的2个节点:

        r
       / \
      a   b
     /
    c
    

    并且说
    c
    知道它的父对象是
    a
    ;在你做了“泛型交换”之后,代码> C <代码>仍然认为对象<代码> a < /代码>是它的父,但是<代码> a <代码>会认为它没有子和<代码> b>代码>考虑<代码> c>代码>为子。< 1 >回答“Python总是使用常数引用对象的传递参数”。

    第2个问题的答案是:不,您不能用一般的方法来做,要找到一些反例,假设您想交换树中的2个节点:

        r
       / \
      a   b
     /
    c
    

    并且说
    c
    知道它的父对象是
    a
    ;在你做了“泛型交换”之后,代码> C <代码>仍然认为对象<代码> a < /代码>是它的父,但是<代码> a <代码>会认为它没有子和<代码> b>代码>考虑<代码> c>代码>为子。< 1 >回答“Python总是使用常数引用对象的传递参数”。

    第2个问题的答案是:不,您不能用一般的方法来做,要找到一些反例,假设您想交换树中的2个节点:

        r
       / \
      a   b
     /
    c
    

    并且说
    c
    知道它的父对象是
    a
    ;在你做了“泛型交换”之后,代码> C <代码>仍然认为对象<代码> a < /代码>是它的父,但是<代码> a <代码>会认为它没有子和<代码> b>代码>考虑<代码> c>代码>为子。< 1 >回答“Python总是使用常数引用对象的传递参数”。

    第2个问题的答案是:不,您不能用一般的方法来做,要找到一些反例,假设您想交换树中的2个节点:

        r
       / \
      a   b
     /
    c
    

    并且说
    c
    知道它的父对象是
    a
    ;在你做了“泛型交换”之后,代码> C >代码>仍然认为对象<代码> a <代码>是它的父,但是<代码> a <代码>会认为它没有子和<代码> b>代码>考虑<代码> c>代码>作为它的子。

    你正在做的是交换这些对象的内容。该函数之外的变量仍然引用它们以前引用的相同对象。只需在调用swap函数之前和之后对这些变量中的任何一个调用
    id
    。所以不,没有“传统交换”。你在那里做的是交换那些对象的内容。该函数之外的变量仍然引用它们以前引用的相同对象。只需在调用swap函数之前和之后对这些变量中的任何一个调用
    id
    。所以不,没有“传统交换”。你在那里做的是交换那些对象的内容。该函数之外的变量仍然引用它们以前引用的相同对象。只需在调用swap函数之前和之后对这些变量中的任何一个调用
    id
    。所以不,没有“传统交换”。你在那里做的是交换那些对象的内容。该函数之外的变量仍然引用它们以前引用的相同对象。只需在调用swap函数之前和之后对这些变量中的任何一个调用
    id
    。所以没有,没有“传统交换”。