Python Revisited (变量)
@
首先,需要指出的是,Python的变量采用的是对象绑定的方式,在程序运行过程中,要时刻注意,对象的变化和共享。
=
第一种情况 = 右边是值 这种情况并不会产生歧义
a = 1
a = '1'
a = [1]
a = {1:'1'}
第二种情况 = 右边是对象引用(变量——个人的说法)
b = 1
a = b
当变量(b)为固定类型——float, int, str, frozenset, tuple等等都是没关系的。
当变量为可变的数据类型——dict, list, set, 就存在风险。
b = [1, 2, 3]
a = b
a[0] = 4
a, b # ([4, 2, 3], [4, 2, 3])
浅拷贝
b = a[ : ] #a 为列表 这种情况是浅拷贝 比=略强
a = [1, ['2', 5], 3]
b = a[:]
a[0] = 2
b[1][0] = 'two'
a, b #([2, ['two', 5], 3], [1, ['two', 5], 3])
以下复制的方式都是浅拷贝:
.copy()
dict()
list()
set()
a[:]
深拷贝`
a = [1, ['2', 5], 3]
b = copy.deepcopy(a)
a[0] = 2
b[1][0] = 'two'
a, b #([2, ['2', 5], 3], [1, ['two', 5], 3])
函数的默认参数为可变类型时 危险
def append_if_even(x, lst=[]): #从对象绑定的角度考虑,合情合理
if x % 2 == 0:
lst.append(x)
print(lst)
append_if_even(2) #[2]
append_if_even(2) #[2, 2]
append_if_even(2) #[2, 2, 2]
append_if_even(2) #[2, 2, 2, 2]
全局变量与临时变量
函数里面创建的变量属于临时变量,在这上面摔的跤太多了。
global
def remain():
global REMAIN
REMAIN = 3
def sum_and_add(a, b):
remain() #得执行一次
return a + b + REMAIN
sum_and_add(1, 2) # 6
在函数里面进行复制
就像在上面讲的,=只是赋值,在函数里面玩这种很容易就凉凉。
def test(a):
b = a # a 属于 list 如果你不希望改变a的值可以采用 b= a[:] 如果是多重的可以考虑深拷贝
b.append(1)
a = [1]
test(a)
a #[1, 1]
再看一个例子
def main():
a = [1]
print(id(a))
ccc(a)
print(id(a))
print(a)
def ccc(a):
a= sorted(a) #这一步令a指向了新的内存地址,所以下面对a操作都不会影响最初的a
print(id(a))
a.append(1)
print(id(a))
ccd(a)
def ccd(a):
a.append(1)
print(id(a))
main()
"""
2431712245320
2431712245512
2431712245512
2431712245512
2431712245320
[1]
"""
def main():
a = [1]
print(id(a))
ccc(a)
print(id(a))
print(a)
def ccc(a):
a.sort() #并没有改变a的指向,不过需要注意的是 [].sort() is None
print(id(a))
a.append(1)
print(id(a))
ccd(a)
def ccd(a):
a.append(1)
print(id(a))
main()
"""
2431712245384
2431712245384
2431712245384
2431712245384
2431712245384
[1, 1, 1]
"""
numpy里的bug?
ndarray里面用id蛮奇怪的,list是都不一样的,同学说可能是沿袭了C。
A = np.array([[1, 2], [3, 4]])
print(id(A))
for i in range(2):
for j in range(2):
print(id(A[i, j]))
#2392090756480
#2392073432760
#2392073432760
#2392073432760
#2392073432760
下面这个例子,符合我们的预期
A = np.arange(4).reshape(2, 2)
a = A[0,...]
print(id(a[0]), id(A[0, 0]), id(A[1, 1]))
a[0] = 999
print(id(a[0]), id(a[1]), id(A[0, 0]), id(A[1, 1]))
a, A
#2392073432160 2392073432160 2392073432160
#2392073432160 2392073432160 2392073432160 2392073432160
#[121]:
#(array([999, 1]), array([[999, 1],
# [ 2, 3]]))
下面的例子就不是了,为什么不改呢?
A = np.arange(4).reshape(2, 2)
a = A[np.array([[True, False], [False, True]])]
#a = A[[0, 1], [0, 1] 同样不行
print(id(a[0]), id(A[0, 0]), id(A[1, 1]))
a[0] = 999
print(id(a[0]), id(a[1]), id(A[0, 0]), id(A[1, 1]))
a, A
#2392073432064 2392073432064 2392073432064
#2392073432064 2392073432064 2392073432064 2392073432064
#(array([999, 3]), array([[0, 1],
# [2, 3]]))
待续
Python Revisited (变量)的更多相关文章
- 配置python环境变量(转)
默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1.首先需要在系统中注册python环境变量:假设python的安装路 ...
- python学习 变量的操作 与 基本数据类型
一变量(本文使用python3.5): #变量:是计算机内存中的一块区域,变量可以存储规定范围内的值,变量可以改变#在python中变量是计算机内存中数据的引用 python的变量没有明显的类型,具体 ...
- python的变量传递
python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式. 这种方式相当于传值和传引用的结合 ...
- Python中变量的作用域(variable scope)
http://www.crifan.com/summary_python_variable_effective_scope/ 解释python中变量的作用域 示例: 1.代码版 #!/usr/bin/ ...
- Windows下python环境变量配置
默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册python环境变量:假设python的安装 ...
- windows7下python环境变量配置
默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行或cmd里直接使用python命令. 1. 首先需要在系统中注册python环境变量:假设pyth ...
- FAQ:Python环境变量配置
Python安装安装成,需要配置环境变量: 默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册 ...
- python基础(2):python的变量和常量
今天看看python的变量和常量:python3 C:\test.py 首先先说一下解释器执行Python的过程: 1. 启动python解释器(内存中) 2. 将C:\test.py内容从硬盘读入内 ...
- python __name__ 变量的含义
python __name__ 变量的含义 if __name__ == '__main__': tf.app.run() 当python读入程序时,会初始化一些系统变量.如果当前程序是主程序,__n ...
随机推荐
- Oracle游标的使用示例
此文是使用Oracle游标的几种方式,for...in会自动打开游标,fetch...into需要手动打开游标,游标类似于一个只会往前移动的指针,每次指向数据集中的一行数据,通过游标可以打开数据集,也 ...
- [日常] imap协议读取邮件
telnet imap.sina.net 143 A01 LOGIN shihan@appdev.sinanet.com 密码 A02 list "" * //列出邮件夹 * LI ...
- C# 操作Word 中的OLE——插入、编辑、读取 OLE
概述 OLE,Object Linking and Embedding,即对象连接与嵌入.我们在设计程序时,OLE可以用来创建复合文档,把文字.声音.图像.表格.应用程序等类型的信息组合在一起,在Wo ...
- linux学习笔记-linux主机上传下载文件至linux虚拟机的方法
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.上传文件 scp -r file 用户名@ip地址:目标目录 2.下载文件 scp -r 用户名@ip地址:文件 目标目录
- Windows中通过命令行新建文件夹、新建文件,和一些常用命令
新建文件 和Linux不太一样,Linux中的touch和vi命令创建新文件的方法都不能用了,在windows命令行下得用type nul>文件名.后缀名来创建: F:\study\vue\wo ...
- 纯CSS修改checkbox复选框样式-02
我有用过这个纯修改input属性的 本人修改后的代码和效果图(修的不好), 这个是改动最简单的: css代码 input[type=checkbox]{ visibility: hidden; } i ...
- 2018年IOS/Android UI设计规范
更多参考: 2017最新设计尺寸及规范 UI : 2018年IOS/Android UI设计规范 转载:https://www.jianshu.com/p/03e5cdd4ffd6
- ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门
一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)分部视图简介 ASP.NET Core MVC (Razor)分部视图基础教程 ASP.NET Core MVC (Raz ...
- Xamarin 开发过的那些项目
您可能已经看到类似的统计数据:智能手机用户在手机媒体上花费了89%的时间使用应用程序.或者听说Gartner预测到2017年移动应用程序下载将产生价值770亿美元的收入.很难不考虑这些数字.今天,每个 ...
- Python高级应用(3)—— 为你的项目添加验证码
验证码简介 验证码的作用: 验证码在现在来说,是很常见的东西,可以一定程度的保护网站,比如防止网络爬虫恶意爬取网站数据啊,减少低级的攻击啊什么的.但是高级点的骚操作还是不太好防范,所以现在的验证码平台 ...