Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.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 - Fatal编程技术网

Python修改类范围外的列表

Python修改类范围外的列表,python,Python,我试图在Python中调用在类作用域之外定义的函数,它修改传递的值,而不引用传递的变量,但类作用域中的原始变量会被修改 我已经广泛地使用python来编写脚本,但实际上并没有对类做太多工作。我看了这篇文章,它解释了很多,但并没有真正谈论它。这个变量肯定超出了范围,它是如何变异的 def doSomethingOutOfScope(arr): spv = arr[0] arr[0] = 'S' class Solution: def doSomethingInScope

我试图在Python中调用在类作用域之外定义的函数,它修改传递的值,而不引用传递的变量,但类作用域中的原始变量会被修改

我已经广泛地使用python来编写脚本,但实际上并没有对类做太多工作。我看了这篇文章,它解释了很多,但并没有真正谈论它。这个变量肯定超出了范围,它是如何变异的

def doSomethingOutOfScope(arr):
    spv = arr[0]
    arr[0] = 'S'


class Solution:
    def doSomethingInScope(self, passed_arr):
        print(passed_arr)                  # prints [0, 1, 2]
        doSomethingOutOfScope(passed_arr)  # passed_arr shouldn't get modified
        print(passed_arr)                  # prints ['S', 1, 2] - Why ?

s = Solution()
s.doSomethingInScope([0, 1, 2])

Python列表实际上是可变的,并且是通过引用传递的

Python列表实际上是可变的,并且是通过引用传递的

在Python中,一切都是一个对象,每个对象都是通过引用传递的。因此,基本上,除了重新分配外,您直接对传递的对象所做的任何更改都会实时反映在对象本身上。需要注意的关键是对象的可变性,即通过初始赋值,对象是否是可变的

例如,
str
int
对象是不可变的。注意,
str
int
下没有任何方法可以直接更改对象:

s = 'foo'  # str type
s.upper()  # FOO
print(s)
# foo
请注意
str.upper()
方法如何不改变
s
本身。为了使
s
成为“FOO”,您需要重新分配
s

s = s.upper()
print(s)
# FOO
但是,通过重新分配对象(
obj=…
),它会更改对象引用,其中
id
现在将不同。因此,如果像这样传递
str

def func(string):
    string = string.upper()

func(s)
s
将保持不变,因为在重新分配
string=…
时,
string
将不再具有与
s
相同的对象引用

但是,对于可变对象,只要不重新分配,对象本身就会进行更改:

l = list('abcde')
def func(lst, value):
    lst.append(value)
    # no reassignment

func(l, 'f')
print(l)
# ['a', 'b', 'c', 'd', 'e', 'f']
这是因为对象引用(
id(l)
)在函数中保持不变


综上所述,在您的情况下,如果您想对对象执行某些操作,但不想对其进行变异,您可以传递对象的副本(该副本将具有不同的
id
),或者在本地范围内创建传递对象的副本:

# pass a copy of the object:
def func(lst):
    lst.append('x')
    return lst

func(lst[:])

# OR, create a local object
def out_of_scope(lst):
    temp_lst = lst[:]
    temp_lst.append('x')
    return temp_lst
在这种特殊情况下,
[:]
列表的完整
片段作为另一个对象返回


关于更多信息,这里有一个.

在Python中,一切都是一个对象,每个对象都在引用中传递。因此,基本上,除了重新分配外,您直接对传递的对象所做的任何更改都会实时反映在对象本身上。需要注意的关键是对象的可变性,即通过初始赋值,对象是否是可变的

例如,
str
int
对象是不可变的。注意,
str
int
下没有任何方法可以直接更改对象:

s = 'foo'  # str type
s.upper()  # FOO
print(s)
# foo
请注意
str.upper()
方法如何不改变
s
本身。为了使
s
成为“FOO”,您需要重新分配
s

s = s.upper()
print(s)
# FOO
但是,通过重新分配对象(
obj=…
),它会更改对象引用,其中
id
现在将不同。因此,如果像这样传递
str

def func(string):
    string = string.upper()

func(s)
s
将保持不变,因为在重新分配
string=…
时,
string
将不再具有与
s
相同的对象引用

但是,对于可变对象,只要不重新分配,对象本身就会进行更改:

l = list('abcde')
def func(lst, value):
    lst.append(value)
    # no reassignment

func(l, 'f')
print(l)
# ['a', 'b', 'c', 'd', 'e', 'f']
这是因为对象引用(
id(l)
)在函数中保持不变


综上所述,在您的情况下,如果您想对对象执行某些操作,但不想对其进行变异,您可以传递对象的副本(该副本将具有不同的
id
),或者在本地范围内创建传递对象的副本:

# pass a copy of the object:
def func(lst):
    lst.append('x')
    return lst

func(lst[:])

# OR, create a local object
def out_of_scope(lst):
    temp_lst = lst[:]
    temp_lst.append('x')
    return temp_lst
在这种特殊情况下,
[:]
列表的完整
片段作为另一个对象返回

关于更多信息,这里有一个例子