python笔记(一)
深拷贝、浅拷贝:
可变类型:
copy: 会生成一个新的对象
如果是列表或者字典, 容器中的元素只是拷贝了引用
deepcopy: 会生成一个新的对象
如果是列表或者字典, 容器中的元素会拷贝一份全新的
不可变类型:
copy: 仅仅增加了一个原来对象的引用
deepcopy: 元组中如果是不可变类型就增加引用,如果元组中是课表类型,就是拷贝一份全新的, 并且元组中的元素也都是全新的
私有属性:
xx: 公有变量,全局共享
_x: 单前置下划线,私有化属性或方法,from somemodule import *禁止导入,类对象和子类可以访问
__xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到),子类继承不到
__xx__:双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 不要自己发明这样的名字
xx_:单后置下划线,用于避免与Python关键词的冲突,不建议使用关键词_.
父类中属性名为__名字的,子类不继承,子类不能访问
如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性
_名的变量、函数、类在使用from xxx import *时都不会被导入
import 导入模块:
import xx 在A模块中定义了一个全局的变量B指向了导入的B模块
from xx import *
import xx,yy 导入两个模块
from xx import aa,bb
import xx as XX
程序执行时,可添加新的路径
import sys
path = sys.path
path.insert(0,'./') # 插入当前路径,放在第一位
print(path)
模块被导入后,import module不能重新导入模块,重新导入需用reload
from imp import reload
import aa # aa模块是我本地的aa.py文件 ,如果程序运行了,我做了修改就不立即生效
reload(aa) # reload 就可以弥补这个缺陷,重新导入
# reload 不适用一个文件,已运行就立即结束
# reload 适合用于永远都运行的项目,改了配置文件,就会立即生效,常见于服务器
模块对应的版本不同,名字可能不一样,
多模块开发时的注意点:
如果想某个模块里面的变量共享,就是用import 导入模块名;
import 模块名 能够在不同的模块中共享数据
多继承和MRO顺序
多继承中,如果使用父类名进行重写,将会导致重写多次;如果使用super进行重写,每个父类都只会被执行一次.所以建议,使用多继承中使用super进行重写
多继承中,如果使用父类名进行重写,将会导致重写多次;如果使用super进行重写,每个父类都只会被执行一次.所以建议,使用多继承中使用super进行重写
1、super\(\).\_\_init\_\_相对于类名.\_\_init\_\_,在单继承上用法基本无差
2、但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果
3、多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
4、单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错
5、多继承时,相对于使用类名.\_\_init\_\_方法,要把每个父类全部写一遍
6、而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
静态方法和类方法:
实例属性属于对象;
类属性属于类;
类属性在内存中只能保存一份数据;
实例属性每个对象都会保存一份,并且数据独立,各对象间数据互不影响;
使用场景:通过类创建实例对象时,如果想每个对象都有一个一样的属性或者名字,就可以使用类属性,保存一份数据;
实例方法、静态方法和类方法:
实例方法:是通过对象调用,至少一个self参数,会将对象自己作为参数传给self;
类方法:是由类调用,至少一个cls参数,会将类自己赋值给cls;
静态方法:是由类调用,无默认参数;
总结:实例对象,一般情况下,只能对象调用,类不可以调用
类方法和静态方法,用类名和对象名都可以调用,但始终在内存中是一份属于类。
property属性:
property属性有两种方式,
一个是装饰器@,在方法上面使用@property
另一个是类属性, 在类中定义值为property对象的类属性
经典类:中的属性只有一种访问方式,其对应被 @property 修饰的方法
新式类:中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
在使用类属性时,经典类和新式类无差别。
定义property属性共有两种方式,分别是【装饰器】和【类属性】,而【装饰器】方式针对经典类和新式类又有所不同。
通过使用property属性,能够简化调用者在获取数据的流程
#coding=utf-8
# ############### 定义 ###############
class Goods:
"""python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
"""
@property
def price(self):
print('@property')
@price.setter
def price(self, value):
print('@price.setter')
@price.deleter
def price(self):
print('@price.deleter')
# ############### 调用 ###############
obj = Goods()
obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price # 自动执行 @price.deleter 修饰的 price 方法
下面由类属性方式创建property属性,具有获取、修改、删除、属性信息描述;
class Goods(object):
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
def get_price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price
def set_price(self, value):
self.original_price = value
def del_price(self):
del self.original_price
PRICE = property(get_price, set_price, del_price, '价格属性描述...')
obj = Goods()
obj.PRICE # 获取商品价格
obj.PRICE = 200 # 修改商品原价
del obj.PRICE # 删除商品原价
魔法属性:
1、__doc__ 表示类的描述信息
2、__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
3、__init__ 初始化方法,通过类创建对象时,自动触发执行
4、__del__ 当对象在内存中被释放时,自动触发执行。
5、__call__ 对象后面加括号,触发执行。
6、__dict__ 类或对象中的所有属性,存成字典类型
7、__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
8、__getitem__、__setitem__、__delitem__ 用于索引操作,如字典。以上分别表示获取、设置、删除数据
9、__getslice__、__setslice__、__delslice__ 用于索引操作,切片,如列表