类:
面向过程编程(Procedural Programming)Procedural programming uses a list of instructions to tell the computer what to do step-by-step.
面向过程编程依赖 - 你猜到了- procedures,一个procedure包含一组要被进行计算的步骤, 面向过程又被称为top-down languages, 就是程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。面向对象编程
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
def person(name,age,sex): def init(name, age, sex): pson = { "name": name, "age": age, "sex": sex, "walk": walk, "ask": ask } return pson def walk(person): print("%s 正在走路"%(person["name"])) def ask(person): print("%s 的年龄是%s"%(person["name"],person["age"])) return init(name,age,sex)p1 = person("帅哥","18","男")# print(p1["name"])p1["walk"](p1)p1["ask"](p1) #修改后
class person(object): def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def walk(self): print("%s 正在走路" %self.name) def ask(self): print("%s 的年龄是%s" % (self.name,self.age)) p1 = person("帅哥","18","男") p1.walk() p1.ask()
通过@staticmethod
装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法
class Dog(object): def __init__(self,name): self.name = name @staticmethod #把eat方法变为静态方法 def eat(self): print("%s is eating" % self.name) d = Dog("ChenRonghua")d.eat()
上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
class Dog(object): def __init__(self,name): self.name = name @staticmethod def eat(): print(" is eating")d = Dog("ChenRonghua")d.eat()
类方法通过@classmethod装饰器实现,
类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
class Dog(object): def __init__(self,name): self.name = name @classmethod def eat(self): print("%s is eating" % self.name) d = Dog("ChenRonghua")d.eat()
修改后如下可以执行
class Dog(object): name = "我是类变量" def __init__(self,name): self.name = name @classmethod def eat(self): print("%s is eating" % self.name) d = Dog("ChenRonghua")d.eat() #执行结果 我是类变量 is eating
属性方法的作用就是通过@property
把一个方法变成一个静态属性
class Dog(object): def __init__(self,name): self.name = name @property def eat(self): print(" %s is eating" %self.name) d = Dog("ChenRonghua")d.eat()
调用会出以下错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了
d
=
Dog(
"ChenRonghua"
)
d.eat
输出
ChenRonghua
is
eating
好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later")f = Flight("CA980")f.flight_status航班查询
那现在我只能查询航班状态, 既然这个flight_status已经是个属性了, 那我能否给它赋值呢?
f
=
Flight(
"CA980"
)
f.flight_status
f.flight_status
=
2
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later") @flight_status.setter #修改 def flight_status(self,status): status_dic = {: "canceled",:"arrived",: "departured" } print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) ) @flight_status.deleter #删除 def flight_status(self): print("status got removed...")f = Flight("CA980")f.flight_statusf.flight_status = 2 #触发@flight_status.setter del f.flight_status #触发@flight_status.deleter
多态
继承父类的子类,实例后一起调用的该父类的方法。
封装
__item = "item"
def get_item (self):
return self.__item
隐藏内部数据,只提供接口实现
动态导入,pass
包装:
继承一个内置类并且按照自己的需求改写部分功能。
“”“ 继承的方式 “”” class test(): def __init__(self,y): self.y = yclass List(list): def append(self, p_object): if type(p_object) is str: super(List, self).append(p_object) else: print("只能添加str类型")
“”“ __getattr__方法 “””
class Filehandle(): def __init__(self,fileName,mode="r",encoding="utf-8"): self.file = open(fileName,mode,encoding=encoding) self.mode = mode self.encoding = encoding def write(self,item): log_time = time.strftime("%Y-%m-%d %X") # self.file.write(log_time) self.file.write("%s %s"%(log_time,item)) def __getattr__(self, item): return getattr(self.file,item)
类的特殊成员方法
1, __doc__ 描述信息
2, __module__ 输出模块
3, __class__ 输出类
4, __init__ 构造方法,通过类创建对象时,自动触发执行
5, __del__ 析构方法,当对象在内存中被释放时,自动触发执行
6, __dict__ 查看类或对象中的所有成员
7, __str__ 一个类中如果定义该方法,那么在打印对象时默认输出该方法的返回值
8, __getitem__, __setitem__ , __delitem__
9, __new__\__metaclass__
反射
hasattr(obj,name_str) , 判断一个对象obj里是否有对应的name_str字符串的方法
getattr(obj,name_str) 根据字符串去获取obj对象里对应的方法的内存地址
setattr(obj,"y",z) is equivalent to"x.y = v"
delattr
异常
try:
code
except (error,error2) as e:
print e
except exception as e : #抓住所有错误一般不建议用