python 您所在的位置:网站首页 可作为变量名的规则 python

python

#python| 来源: 网络整理| 查看: 265

本文介绍的是python的基础:先从定义名称 来说 标识符 --> 变量 -->引用--> 深浅赋值

标识符

Python 对各种 变量、方法、函数 等命名时使用的字符序列称为标识符。

也可以说凡是自己可以起名字的地方都叫标识符。

标识符就是一个名字,它的主要作用: 变量、函数、类、模块 以及其他对象的名称。

Python标识符的命名规则

Python 由 26 个英文字母大小写,0-9 ,_ 组成。

Python 不能以数字开头。

Python 严格区分大小写。

Python 不能包含空格、@、% 以及 $ 等特殊字符。

不能以系统保留关键字作为标识符(一共有25 个)。

Python标识符的命名注意事项

尽量采取有意义的包名,简短,有意义,不要和系统保留关键字冲突。

以单下划线开头的标识符,表示不能直接访问的类属性,其无法通过 import 的方式导入。

以双下划线 开头的标识符 表示 类 的私有成员。

以双下划线作为 开头和结尾的标识符,是专用标识符。

Python 标识符是允许使用汉字作为标识符的。

Python标识符规范

当标识符用作模块名时,应尽量短小,并且全部使用小写字母,可以使用下划线分割多个字母。

当标识符用作包的名称时,应尽量短小,也全部使用小写字母,不推荐使用下划线。

当标识符用作类名时,应采用单词首字母大写的形式。

模块内部的类名,可以采用 “下划线+首字母大写” 的形式。

函数名、类中的属性名和方法名,应全部使用小写字母,多个单词之间可以用下划线分割。

常量命名应全部使用大写字母,单词之间可以用下划线分割。

总结

对各种变量、方法、函数等命名时使用的字符序列称为标识符。

由 26 个英文字母大小写,0-9 ,_ 组成,不能以数字开头,且严格区分大小写。

不能包含空格、@、% 以及 $ 等特殊字符,不能以系统保留关键字作为标识符(一共有25 个)。

Python 中,以下划线开头的标识符有特殊含义。

变量 概念

首先他是弱类型语言 ,在Python中,变量是没有类型的

在使用变量的时候,不需要提前声明,只需要给这个变量赋值即可。

但是,当用变量的时候,必须要给这个变量赋值;如果只写一个变量,而没有赋值,那么Python认为这个变量没有定义。

变量的类型:

Number

数字

String

字符串类型

Tuple

元组

List

列表

Set

集合

Dictionary

字典

变量无类型,对象有类型

总结来说:在Python中,类型是属于对象的,而不是变量,

变量和对象是分离的,对象是内存中储存数据的实体,变量则是指向对象的指针。

引用 引用的概念

python中所谓的赋值: 其实传的是对象指向的引用,也就是说传的是地址。

任何一个python对象都有标签,类型和值三个属性。

标签在对象创建后 直到内存回收就保持不变,可以理解为内存地址。

python在给变量赋值,会把赋值的对象的内存地址赋值给变量,也就是说python的变量是地址引用式的变量。

引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的值本身。

可以通过is或者比较id()的判断是否引用的是同一个内存地址的变量。

== 是比较两个对象的内容是否相等,即两个对象的值是否相等 is同时检查对象的值和内存地址。可以通过is判断是否是同一个对象 id() 列出变量的内存地址的编号 引用同时要考虑 对象的因素

python中的一切都是对象。对象: 又分为可变对象和不可变对象。

二者的区别在于对象的值在不改变内存地址的情况下是否可修改。

可变对象包: 字典dict、列表list、集合set、手动声明的类对象等 不可变对象: 数字int float、字符str、None、元组tuple等 list 可变对象,内容变更地址不变 a = [1, 2, 3] print(id(a)) a.append(5) print(id(a)) 不可变对象(常用的共享地址或缓存)# 较小整数频繁被使用,python采用共享地址方式来管理 a = 1 b = 1 print(a is b) # True # 对于单词类str,python采用共享缓存的方式来共享地址 a = 'hello' b = 'hello' print(a is b) # True 不可变对象(不共享地址) a = (1999, 1) b = (1999, 1) print(a is b) # False a = 'hello everyone' b = 'hello everyone' print(a is b) # False 元组的相对不可变型 # 元组的里元素是可变,改变可变的元素,不改变元组的引用 a = (1999, [1, 2]) ida = id(a) a[-1].append(3) idb = id(a) print(ida == idb) # True

这里之提到变量可变和不可变的特性

主要想说的是: 1. 变量的引用:和 变量可变、不可变没有直接的关系。

2. 是变量 可不可以修改,注意这个修改不是通过赋值的操作来完成。

# 前后两个变量a, 已经不是同一个地址了 a = [1, 2, 3] print(id(a)) a = a + [5] print(id(a)) 函数参数的引用

函数的传参方式是共享传参,即函数的形参是实参中各个引用的副本(别名)。

函数会修改是可变对象的实参(表示的同一个对象);而不会改变实参的引用。

def func(d):     d['a'] = 10     d['b'] = 20 # 改变了外部实参的值     d = {'a': 0, 'b': 1} # 赋值操作, 局部d贴向了新的标识     print(d) # {'a': 0, 'b': 1} d = {} func(d) print(d) # {'a': 10, 'b': 20}

建议不要写上面例子的代码,局部变量和全局变量的名称一样,尽量编码,否则很容易出bug而不自知。

函数的参数的 默认值避免使用可变参数,尽量用None来代替。原因是函数的默认值是作为函数对象的属性,如果默认值是可变对象,而且修改了它,那边后续的函数对象都会受到影响。

深浅赋值【拷贝】

由上面的顺下来就可以看出值的引用,由此可以引出深浅赋值的概念。

浅拷贝和深拷贝

对于可变对象,我们要时刻注意它的可变性,特别是对赋值或者拷贝后的变量做内容修改操作的时候,需要考虑下是否会影响到原始变量的值,如果程序有bug,可以往这方面想一想。这里讲一下拷贝即建立副本。拷贝有两种:

dict1 = {'user':'runoob','num':[1,2,3]} dict2 = dict1 # 浅拷贝: 引用对象 dict3 = dict1.copy() # 浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用 # 修改 data 数据 dict1['user']='root' dict1['num'].remove(1) # 输出结果 print(dict1) print(dict2) print(dict3)

实例中 dict2 其实是 dict1 的引用(别名),所以输出结果都是一致的,dict3 父对象进行了深拷贝,不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改。

{'num': [2, 3], 'user': 'root'} {'num': [2, 3], 'user': 'root'} {'num': [2, 3], 'user': 'runoob'}

copy和deepcopy均是开辟了新的内存空间

不可变对象的话因为是拷贝值, 所以原被拷贝对象中不可变对象的变化并不会影响到拷贝后的对象.

浅拷贝:copy 浅复制的值:不可变对象: int、tuple、str、bool

两者中的元素具有相同的内存地址。对象的id值与浅复制原来的值相同。

>>> a="1234567" >>> b=a # 对不可变对象的引用 >>> id(a)4367619440 # 两者中的元素具有相同的内存地址 >>> id(b)4367619440 # 两者中的元素具有相同的内存地址 >>> c=copy.copy(a) >>> id(c)4367619440 # 两者中的元素具有相同的内存地址 >>> d=copy.deepcopy(a) >>> id(d)4367619440 # 两者中的元素具有相同的内存地址 当浅复制的值是可变对象 第一种情况:浅复制的值是可变对象(列表,字典)时,改变的值不是 复杂子对象

原值的改变 ---- 不会影响浅复制的值,

浅复制的值改变----不会影响原来的值。

原值的id值----浅复制的原值----不同。

>>> l1=[1,2,3] >>> l2=l1 # 对可变对象的引用 >>> id(l1) 4367654664 # 原来值的ID >>> id(l2) # l1 和 l2 两者中的元素具有相同的内存地址 4367654664 >>> l1.append(55) # 原来的值 >>> print(l1) # 原来值的改变 [1, 2, 3, 55] l3=copy.copy(l1) # 不会影响浅复制的值,同时浅复制的值改变也并不会影响原来的值 >>> id(l3) 4367628616 # 原来值的id值与浅复制 的ID不同。 >>> print(l3) [1, 2, 3] 第二种情况:复制的对象中有 复杂 子对象 (例如 列表中的一个子元素是一个列表)

不改变其中复杂子对象,改变原来的值 并不会影响 浅复制的值

改变原值 中的复杂子对象的值 会影响浅复制的值。

当浅复制的值是可变对象(列表,字典)时,改变的值是 复杂子对象 >>> import copy >>> list1=[1,2,['a','b']] # 复制的对象中有 复杂 子对象 一个子元素是一个列表 >>> list2=list1 >>> id(list1) 4338414656 # l1 和 l2 两者中的元素具有相同的内存地址 >>> id(list2) 4338414656 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> list3=copy.copy(list2) >>> id(list3) 4338415016 # l3 和 l2 两者中的元素有不相同的内存地址 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>> list1[2].append('a') # 改变原来的值 中的复杂子对象的值 >>> id(list1) 4338414656 >>> print list1 [1, 2, ['a', 'b', 'a']] >>> print list3 # 会影响浅复制的值。 [1, 2, ['a', 'b', 'a']] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>> list1.append(33) # 改变原来的值 >>> id(list1) 4338414656 >>> id(list3) 4338415016 # 不会影响浅复制的内存地址。 >>> print list1 [1, 2, ['a', 'b', 'a'], 33] >>> print list3 # 不会影响浅复制的值。 [1, 2, ['a', 'b', 'a']] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 深拷贝 deepcopy

定义

深复制,被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。

总结

a b是不相同的内存地址,

ab中的元素内存地址也不相同,两者完全独立。

a中的可变对象发生改变的话不会影响b中对象的改变。

list1=[1,2,['a','b']] # 原地址 >>> id(list1) 4338414656 list3=copy.copy(list2) # 浅复制 >>> id(list3) 4338415016 list4=copy.deepcopy(list3) # 深复制 >>> id(list4) 4338414368 # 不会影响深复制的内存地址。 因为是新开的 两者完全独立。 >>> print list4 [1, 2, ['a', 'b']] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>> list1.append(33) # 改变原来的值 print list1 [1, 2, ['a', 'b', 'a'], 33] list1[2].append('a') # 改变原来的值 中的复杂子对象的值 >>> print list1 [1, 2, ['a', 'b', 'a']] print list4 [1, 2, ['a', 'b']] # 可变对象发生改变的话不会影响b中对象的改变


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有