包(lib)、模块(module)
模块:编写Python代码的py文件
包:用来分门别类存放模块代码的文件夹,【一般存在一个init.py文件】
一般创建一个包都会存在一个init.py文件用来导入其他模块文件
你调用模块的时候会自动生成一个缓存文件夹 要有缓存文件才可以导入 模块
必须要有这个缓存才可以用如果直接引用别的文件夹的模块不会成功
必须在这个init包里写入其他模块才可以导入只要声明了就能直接导入
使用all=[] 方法导入
from 包名称 import * 这样就会生成init中所有的缓存模块的,前提是必须将模块写进init中
==和is使用:
. is 是比较两个引用是否指向了同一个对象(地址引用比较)
== 是比较两个对象是否相等。(比较的数值)
举例:
a=10
b=10
a==b
True
a is b
True
is代表的是不是指向同一个内存地址结果返回布尔
指向的是不是同一个堆,平时申请的数据类型都是在栈里面申请的
平常申请的-5~256数据都是在小整形缓冲数据里面存放
超过256或者小于-5都会返回false内存地址改变
赋值:
将一个变量赋值给另一个变量,这个过程叫做赋值。
赋值会导致多个变量同时指向一块内存,所以此时不管是==或者is都返回True
当a赋值给b的时候也会把内存地址赋值给b 栈里面存放的是地址 他俩同时指向了堆
用id(列表名称)来进行查询内存地址
浅拷贝:
. 首先我们需要先引入我们的模块import copy
此时他们两个的内存地址和指向的堆都不一样
浅拷贝只能拷第一层也就是顶层数值,如果修改a或b里面第二层还是会发生变化
只修改第一层的数值b就不会发生变化了
深拷贝:
. 我们深拷贝的方法名称为deepcopy
深拷贝可以拷贝里面所有的列表,所以不会发生变化
注意:
如果将列表改成元祖[]>()>" " 字符串也一样 他们都指向数据区的同一块值 他们出来的id地址都一样跟赋值一样
1.4.2使用property升级getter和setter方法
Python内置的@property装饰器就是负责把一个方法变成属性调用的:
@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@name.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:
class User():
def __init__(self,name):
self.__name=name
@property 用我们python提供的@property方法,表示我要对name这个方法进行标识
def name(self):
return self.__name
@name.setter 这个表示是name的setter方法
def name(self,name):
self.__name=name
def shuo(self):
print("名字"+str(self.__name))
if __name__=="__main__":
a=User("赵某某",18,"男")
#a.set_name("刘某某")
a.name="刘某某"
print(a)
a.shuo()
小结
作用:
将方法转换为只读
重新实现一个属性的设置和读取方法
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性