sorted()排序要巧用元组
常见的三种编程范式
函数式编程
• 函数可以作为参数传递、修改,或作为返回值
• 函数内不修改外部变量的状态
面向过程编程 (函数)
• 根据操作数据的语句块来实现功能。
面向对象编程 (OOP-Object Oriented Programming)
• 把数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法
面向过程着重于做什么
面向对象着重于谁去做
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合
类:用来描述具有相同的属性和方法(能做的事)的对象的集合(如:下面有很多车)
属性:对象的描述信息(有什么特性)(数据)
方法:对象的行为(能做什么)(函数)
对象(也可以叫实例):通过类定义的数据结构实例(如:冯老师的那辆车)
类:class 只是一个模板,不能做事情 所以得实例化变成对象,对象是类的实例
之前是函数的封装,类就是再数据和函数外面再进行一层封装
面向对象:多用于大程序 新加功能很方便 应付于版本迭代更新 程序结构清晰明了
类只关注有什么属性能做什么事情
具体怎么做,如何做由主程序来实现
基类和子类:车(基类) -> 公交车/摩托车/大卡车/摩托车/拖拉车/小轿车(子类)
子类继承父类的一切方法和属性 也可以有自己的特点
类的基本特点(常考)
• 封装(Encapsulation)
• 在类中对数据的赋值、内部调用对外部用户是透明的。
• 把一些功能的实现细节不对外暴露
• 继承(Inheritance)
• 继承:即一个派生类(也就是子类)继承基类的字段和方法。
• 为实现代码的重用, 一个类可以派生出子类
• 继承也允许把一个派生类的对象作为一个基类对象对待。
• 多态(Polymorphism)
• 接口重用
• 一个接口,多种实现(重写)
类的定义和使用:
类的定义:
类名:一般首字母大写 (驼峰命名)
函数命名:由小写字母和下划线组成
python2的主流版本是2.7
python3的主流版本是3.6及之后版本
python2--经典类和新式类
只有显式的继承了object的类称为新式类,其他都是经典类
python3--新式类
默认都是object,所以都是继承新式类
经典类和新式类最大区别就在于有没有继承python的内置类(object)
如:
class A():
pass
class B:
pass
class C(object):
pass
在python2里面只有C是新式类 其他都是经典类
而在python3里面都是新式类
定义 调用 及 修改:
class ATM():
money=50000
def draw_money(self,getmoney):
if getmoney <= self.money:
#self代表实力本身
#self.money(实例(a)的money)=self.money(最开始是原始类的money)-getmoney
self.money-=getmoney
print(f"取了{getmoney},还剩余{self.money}")
else:
print("余额不足")
#实例化
a=ATM()
b=ATM()
#属性和方法的访问
#a取取500,a取的钱不影响b里面的钱,两者完全独立
a.draw_money(500)
print(a.money)
#属性的修改 修改a的不影响b 还可以增加属性
a.money=60000
a.area="cahngsha" #只定义了a的area属性,b里面没有area属性
#也可以通过类去访问变量 也可以直接创建变量
print(ATM.money) #输出50000
ATM.area='hunan'
#删除属性方法
del a.area
类空间和实例空间:
类创建的时候会生成类空间
实例化对象的时候就会生成实例空间,不同的实例,空间都是独立的
实例查找属性方法的时候,现在自己的实例空间找,
找不到就去类空间查找(实例空间里面有一个指针指向类空间),
类空间找不到就去父类找,一层一层往上找
#self代表实例本身 代表实例 如a=ATM() 则里面的self代表a
实例只能访问类,不能更改
实例化的时候是没有一起把属性和方法拷贝过来(只是指针指向),需要调用的时候才会拷贝更改
赋值的话就没有必要去类里面查找,实力空间有就直接修改,没有的话就是赋值
相关的图看微信截图!!!!
为什么实例可以访问类属性?
创建实例的时候,会有一个类对象指针,通过这个指针,实例就能访问类的属性方法(通过.的方式)
__init__方法:(按需求写 需要的时候就写)
实例对象的构造方法(初始化方法)
实例化对象的时候就会自动调用__init__方法
实例空间里面就有这里面的属性 但是类空间没有
__init__的参数需要在实例化的时候传参
如
class ATM():
def __init__(self,area):
self.area=area
self.bank="jianshe"
实例化的时候 a=ATM("changsha")
__new__方法:
创建实例,一般情况下不需要重写,基本上用不到
创造实例(a=ATM())的时候一定会先调用__new__方法
如果类里面没有写__new__方法 ,则会继承object的__new__方法
class ATM():
def __new__(cls, *args, **kwargs):
#*args:可变长的位置参数(元组) **kwargs:可变长的关键字参数(字典) (这是为了照顾后面需要参数的__init__方法)
#使__new__这个方法更加通用(一般*args, **kwargs都是为了更加通用)
print("this is new method:",cls)#cls代表类class 输出this is new method:
print(args,kwargs)#输出() {}
return object.__new__(cls)
a=ATM()
print(a)
#若没加return object.__new__(cls)这个__new__方法没有返回任何东西,就会输出None
#若加上 则会返回<__main__.ATM object at 0x000001D6E93889D0>
a=ATM()
先会用__new__创建一个实例 然后返回的自身类产生的实例才会自动交给__init__方法
总结:
__new__是创建实例的方法
__init__对创建的实例进行初始化工作的方法
__new__方法必须要传入一个参数(cls),代表当前类
__new__必须要返回一个实例化对象
__init__的self就表示__new__方法返回的实例,__init__就对这个实例进行初始化工作
子类没有定义__new__,就会去找父类的__new__
新式类才有__new__
如果实例化对象和本身cls不一致,__init__就不会执行
__new__方法属于静态方法(前面有@staticmethod)
__init__方法属于实例方法(有self)
类属性和实例属性:
class ATM():
money=50000 #类属性
def __init__(self,area):
self.area=area #实例属性
self.bank="jianshe" #实例属性