python建立子函数,在主程序中进行调用。
将全局变量传入子函数,子函数中对局部变量进行修改导致全局变量发生。
示例代码:
import numpy as np
def softmax(lx):
lx -= np.max(lx, axis = 1, keepdims = True)
print("lx:\n",lx)
print("全局变量x地址与局部变量地址是否相同:", id_x==id(lx))
lx = np.exp(lx) / np.sum(np.exp(lx), axis = 1, keepdims=True)
return lx
x = np.array([[5,3,1,1],[0.5,0.3,0.1,0.1]])
print("运算前X:\n",x)
id_x = id(x)
y = softmax(x)
print("运算后X:\n",x)
print("y:\n",y)
代码结果:
运算前X:
[[5. 3. 1. 1. ]
[0.5 0.3 0.1 0.1]]
lx:
[[ 0. -2. -4. -4. ]
[ 0. -0.2 -0.4 -0.4]]
全局变量x地址与局部变量地址是否相同: True
运算后X:
[[ 0. -2. -4. -4. ]
[ 0. -0.2 -0.4 -0.4]]
y:
[[0.85326667 0.11547709 0.01562812 0.01562812]
[0.31651871 0.25914361 0.21216884 0.21216884]]
在 python 中,对象才有类型,变量是没有类型的(例如:a=5, 那么5就是对象,int型;a是变量,没有类型,是一个对象的引用(一个指针))。
对象的类型可以分为两类:
1.不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
2.可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
1.不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
2.可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
使用copy函数,将全局变量的值传递给局部变量。
import numpy as np
def softmax(llx):
lx = llx.copy()
lx -= np.max(lx, axis = 1, keepdims = True)
print("lx:\n",lx)
print("全局变量x地址与局部变量地址是否相同:", id_x==id(lx))
lx = np.exp(lx) / np.sum(np.exp(lx), axis = 1, keepdims=True)
return lx
x = np.array([[5,3,1,1],[0.5,0.3,0.1,0.1]])
print("运算前X:\n",x)
id_x = id(x)
y = softmax(x)
print("运算后X:\n",x)
print("y:\n",y)
代码结果:
运算前X:
[[5. 3. 1. 1. ]
[0.5 0.3 0.1 0.1]]
lx:
[[ 0. -2. -4. -4. ]
[ 0. -0.2 -0.4 -0.4]]
全局变量x地址与局部变量地址是否相同: False
运算后X:
[[5. 3. 1. 1. ]
[0.5 0.3 0.1 0.1]]
y:
[[0.85326667 0.11547709 0.01562812 0.01562812]
[0.31651871 0.25914361 0.21216884 0.21216884]]
参考文档