1.类属性和实例属性
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,对于公有的类属性,可以通过类或者实例对象访问
实例属性只能通过对象来调用,类不能调用
通过实例(对象)去修改类属性
对象修改类属性,只对本对象有效果,对别的
对象没有影响
类方法
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数,可以通过对象和类来访问
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引用,调用静态方法可以通过对象或者类调用
总结
类方法使用@classmethod装饰,第一个参数为类(cls),调用时可以通过类的实例或者类本身来调用。
实例方法定义时第一个参数为类的一个实例(self),调用时必须通过实例调用。
静态方法使用@staticmethod装饰,调用时可以使用类的实例或者类本身来调用。
__new__与__init__
总结
1). __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
2). __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
3). __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
4). 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节
单例模式
单例模式:永远用一个对象得实例,避免新建太多实例浪费资源
实质:使用__new__方法新建类对象时先判断是否已经建立过,如果建过就使用已有的对象
eg:class Foo(object):
instance = None
def __init__(self):
self.name = 'alex'
def __new__(cls):
if Foo.instance:
return Foo.instance
else:
Foo.instance = object.__new__(cls)
return Foo.instance
obj1 = Foo()
obj2 = Foo()
print(obj1,obj2
即Foo.instance不为空直接使用,为空用__new__建立
推导式与递归
作用:用一个表达式创建一个有规则的列表或者控制一个有规律列表。
基本写法
列表:[XX for XX in range()]
字典:{xx1:xx2 for ...in ...}
集合:{xx for xx in ...}
列表推导式
eg:创建列表[(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
list[(i,j) for i in range(1,3) for i in range(0,3)]
print(list)
字典推导式
eg:创建一个字典:字典key是1-5数字,value是这个数字的2次方
zd={i:i**2 for i in range(1,5)}
合并列表变成字典
eg:list11=["name","age","sex"]
list22=["jack","30","男"]
zd={list[i]:list[i] for i in range(len(list11))}
注意:如果两个列表的个数相同,len统计任何一个列表长度都可以
如果两个列表的个数不相同,len统计数据多个会报错,len统计数据少的可以
提取目标数值
eg:counts={"lenovo":300,"HP":200,"DELL":100}
提取数量大于300的key
a={key:value for key,value in counts.items() if value>=200}
集合推导式
eg:创建一个集合,数据为下发列表2次方
list=[1,1,2]
b=[i**2 for i range(list)]
递归
递归是一种编程思想,应用场景:
1.日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现:
2.在后续的算法中,很多算法都离不开递归,例如:快速排序.
特点
函数内部自己调用自己
必须有出口
冒泡排序
原理它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成
def moapao(a):
b=len(a)
for j in range(b-1):
for i in range(b-1):
key=a[i+1]
if key<a[i]:
a[i],a[i+1]=key,a[i]
return a
a=[12,42,23,41,11,2,44,34,88,3]
print(moapao(a))
打印结果[2, 3, 11, 12, 23, 34, 41, 42, 44, 88]
快速排序
原理为应用递归的思想在列表中用索引取一个基数,让列表中其他数与基数进行比较,如果比基数小放在左列表,反之放在右列表,两列表依次重复直到列表中元素小于两个为止,将左右列表与base值组成新列表
def quick(a):
if len(a)<2:
return a
else:
base=a[0]
left=[i for i in a[1::] if i<base]
right=[i for i in a[1::] if i>base]
return quick(left)+[base]+quick(right)
a=[1,34,22,13,77,35,29]
print(quick(a))
结果[1, 13, 22, 29, 34, 35, 77]
选择排序
原理:第1趟,在待排序记录r1 ~ r[n]中选出最小的记录,将它与r1交换;第2趟,在待排序记录r2 ~ r[n]中选出最小的记录,将它与r2交换;以此类推,第i趟在待排序记录r[i] ~ r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
def xuanze(a):
leght=len(a)
for i in range(leght):
mi=i
for j in range(i+1,leght):
if a[mi]>a[j]:
mi=j
a[mi],a[i]=a[i],a[mi]
return a
a=[5,8,2,34,22,15,77]
print(xuanze(a))
结果[2, 5, 8, 15, 22, 34, 77]