动态类型的言语
python是动态类型的言语,不需求声明变量的类型。
实际上,python中的变量仅仅仅仅用来保存一个数据目标的地址。不论是什么数据目标,在内存中创立好数据目标之后,都仅仅把它的地址保存到变量名中。所以变量名是类型无关的,但它指向的值是类型相关的,可所以数值、字符串、列表、函数、类、目标等等。这些内存目标中都至少包括3部分:目标类型、目标的引证计数(用来判别改目标是否可被废物收回器收回)、目标的值。
因而,a = 3中,变量名a保存的是数据目标3的地址,之后可认为其赋值一个字符串a = “hello”,这时a保存的是"hello"字符串的地址。在这个类型改动的进程中,a仅仅仅仅修正了一下地址罢了。
变量的命名风格
python中的变量命名时只能包括数字、大小写字母、下划线这三种类型的字符,而且数字不能是首字符。 还有一些有特别含义的变量命名方法(现在这些内容了解即可):
前缀并后缀双下划线的变量,如__ name__,这种类型的变量在python中有特别含义,归于目标的内置特点,今后学了类和目标就知道了
单下划线前缀的变量,如_x,这类变量不会被from ModuleName import *的方法导入
双下划线前缀的变量,如__x,这类变量是类的本地变量或称为类的私有变量,它会扩展成__classname_x
除此之外,还有约定俗成的命名方法:
常量以全大写字符表明
一般变量、函数名、方法名都以小写字母最初命名
模块名、包名以全小写字母命名
类名以大写字母最初
由于仅仅约定俗成,所以没有强制约束。
变量赋值的几种方法细节
本文解说python中变量赋值的方法,并解说一些细节。后边还有一篇文章解说python中按引证赋值的文章。 python中变量赋值的几种方法。
留意:python的数值是不可变目标,无法在原处修正数据,所以不支撑自增、自减。
其间(1)-(3)无需过多解说,仅有必需求分外留意的是,当运用逗号的时分,python总会临时或永久地建立成tuple来保存元素,所以x, y = “long”, "shuai"在内部彻底等价于(x, y) = (“long”, “shuai”)。
实际上,列表元素也能够赋值给元组,或许元组赋值给列表,只需两头的序列元素个数能对应,无所谓左右两头的序列类型:
关于(4)赋值方法,是序列赋值的行为,在python中,只需是序列,都能够这样赋值。正如这儿的变量赋值状况等价于:
假如换成其它的序列也相同。例如:
可是变量和序列中的元素有必要一一对应。假如变量名与元素个数不同,则会报错,除非只需一个变量名,这表明将整个序列赋值给这个变量。
假如想要将序列中的元素赋值给不等的变量,可优先考虑先将序列进行切片。
(5)的赋值方法则正好是让变量名少于元素个数的方法。这种赋值方法称为序列解包(下文会专门解说这种赋值方法),多出来的元素会悉数以列表的方法赋值给最终一个变量名。正如这儿等价于:
下面两种赋值方法得到的成果是相同的,a是字符串,b是列表,b都包括3个元素:
赋值的成果:
(6)的赋值方法等价于:
python赋值时,总是先核算"=“右边的成果,然后将成果依照赋值方法赋值给”="左面的变量。所以,这儿的进程是先将"long"赋值给变量b,再将b赋值给变量a。
由于总是先核算右边,所以交流变量十分的便利。
(7)的赋值方法a += 3在成果上等价于a = a + 3,在其它言语中这两种赋值方法是彻底等价的,但在python中这种增强赋值的方法要比后者更高功率些,为什么功率要高一些,下文会稍作解说。在很大程度上来说,Python中只需是简化的方法,大多数都比更杂乱的等价方法功率更高。
(8)的赋值方法((a, b), c) = (‘lo’, ‘ng’)是将序列进行嵌套序列赋值,将’lo’赋值给元组(a, b),'ng’赋值给c,元组又进一步赋值a=‘l’, b=‘o’。这种赋值方法在python中很好用,特别是在表达式中赋值的时分,比方for循环和函数参数:
关于序列解包
在前面简略介绍了一下序列解包:
当运用一个前缀变量的时分,表明将序列中对应的元素悉数搜集到一个列表中(留意,总是一个列表),这个列表名为最初的那个变量名。*号能够呈现在恣意方位处,只需赋值的时分能前后对应方位联系即可。 留意其间的几个关键字:序列、对应的元素、列表
序列意味着可所以列表、元组、字符串等等
列表意味着只需搜集不报错,赋值给解包变量的一定是一个列表
对应的元素意味着或许搜集到0或恣意个元素到列表。
不论怎么,搜集的成果总是列表,只不过或许是空列表或许只需一个元素的列表。 例如:
两个需求留意的几点:
由于序列解包是依据元素方位来进行赋值的,所以不能呈现多个解包变量
假如将序列直接赋值给单个解包变量时(即没有一般变量),这个解包变量有必要放在列表或元组中
之所以单个解包变量时有必要放在元组或变量中,看下面两个等价的比方就很简单理解了:
最终,序列解包是切片的快捷代替方法。能用序列解包的,都能用切片来完成,但切片要输入额定的各种字符。例如:
必需求分外留意,解包回来的一定是列表,但序列切片回来的内容则取决于序列的类型。例如下面元组的切片回来的是元组,而不是列表:
二元赋值表达式
python支撑类似于a += 3这种二元表达式。比方:
在python中的某些状况下,这种二元赋值表达式或许比一般的赋值方法功率更高些。原因有二:
二元赋值表达式中,a或许会是一个表达式,它只需核算评价一次,而a = a + 3中,a要核算两次。
关于可变目标,能够直接在原处修正得到修正后的值,而一般的一元赋值表达式有必要在内存中新创立一个修正后的数据目标,并赋值给变量
第一点无需解说。关于第二点,看下面的比方:
关于上面(1)和(4)的一元赋值表达式,先获得L,然后创立一个新的列表目标,将L复制到新列表目标中,并将4或5,6放进新列表目标,最终赋值给L。这样的一个进程中触及到了几个过程:新分配内存、内存中列表复制、放入新数据。
而(2)(3)是等价的,(5)(6)也是等价的,它们都是直接在内存中的原始列表处修正,不会有复制操作,新建的数据目标仅仅仅仅一个元素。
依照理论上来说,的确二元赋值方法要功率高一些,但要留意的是,列表中保存的仅仅各元素的引证,所以复制列表也仅仅仅仅复制一点引证,这是微乎其微的开支。所以一元赋值和二元赋值的距离在这一点的性能上根本没距离,首要的距离还在于一元、二元赋值方法或许存在的表达式不同评价次数。
总的来说,运用二元赋值表达式一般可当作可变目标赋值的一种优化手法。