@

首先,需要指出的是,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 (变量)的更多相关文章

  1. 配置python环境变量(转)

    默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1.首先需要在系统中注册python环境变量:假设python的安装路 ...

  2. python学习 变量的操作 与 基本数据类型

    一变量(本文使用python3.5): #变量:是计算机内存中的一块区域,变量可以存储规定范围内的值,变量可以改变#在python中变量是计算机内存中数据的引用 python的变量没有明显的类型,具体 ...

  3. python的变量传递

    python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式.     这种方式相当于传值和传引用的结合 ...

  4. Python中变量的作用域(variable scope)

    http://www.crifan.com/summary_python_variable_effective_scope/ 解释python中变量的作用域 示例: 1.代码版 #!/usr/bin/ ...

  5. Windows下python环境变量配置

    默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册python环境变量:假设python的安装 ...

  6. windows7下python环境变量配置

    默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行或cmd里直接使用python命令. 1. 首先需要在系统中注册python环境变量:假设pyth ...

  7. FAQ:Python环境变量配置

    Python安装安装成,需要配置环境变量: 默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册 ...

  8. python基础(2):python的变量和常量

    今天看看python的变量和常量:python3 C:\test.py 首先先说一下解释器执行Python的过程: 1. 启动python解释器(内存中) 2. 将C:\test.py内容从硬盘读入内 ...

  9. python __name__ 变量的含义

    python __name__ 变量的含义 if __name__ == '__main__': tf.app.run() 当python读入程序时,会初始化一些系统变量.如果当前程序是主程序,__n ...

随机推荐

  1. Ubuntu中安装 mercurial – TortoiseHG

    sudo add-apt-repository ppa:tortoisehg-ppa/releases sudo add-apt-repository ppa:mercurial-ppa/releas ...

  2. Spring Cloud Alibaba基础教程:支持的几种服务消费方式(RestTemplate、WebClient、Feign)

    通过<Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现>一文的学习,我们已经学会如何使用Nacos来实现服务的注册与发现,同时也介绍如何通过LoadBal ...

  3. webpack4.0各个击破(8)—— tapable篇

    webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高.本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习we ...

  4. .Net语言 APP开发平台——Smobiler学习日志:如何在手机中调用邮件发送接口

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 一.目标样式 我们要实现上图中的效果,需要如下的操作: 二.发送邮件代码 VB: Pr ...

  5. array_merge和array+的区别分析

    记得之前发现很多朋友用过array+array的方式,今天索性再聊下这样的话题:如何获取字符键名相同值不同的两个数组值集合?让我认真比较了下PHP中array_merge和array相加的区别 首先来 ...

  6. 折腾Java设计模式之策略模式

    博客原文地址 简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. ...

  7. 20190326-HTML5标签、CSS的引用

    目录 1.HTML5标签 H5前的DIV+CSS布局 H5解决的问题 H5新标签header.footer.nav.aside.article.address.main.figure.figcapti ...

  8. Python全栈之路(目录) - 含资料(持续更新)

    一. Python全栈之路 - 目录 Python基础 Python进阶 网络编程 并发编程 前端 数据库 Python Web框架之Django 前端框架之Vue Linux Flask+智能玩具 ...

  9. python运行逻辑

    Python程序在解释器上执行分两个过程: 编译:如果Python进程在机器上拥有写入权限,那么它会把程序的字节码保存为一个以 .pyc 为扩展名的文件.当程序运行后,会在源代码的同一个目录下看到 . ...

  10. 后端开发者的Vue学习之路(三)

    目录 上节内容回顾 组件 什么是组件 组件注册 全局注册组件 局部注册组件 使用细节 组件注册的命名规范: 组件中只有一个根元素 组件也是一个实例 组件在某些元素中渲染出错 组件间的数据传递 父子组件 ...