面向对象介绍:
1、面向对象有两大特性:
1.1、class:
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
1.2、object:
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
class Dog(object): def __init__(self,name): #构造函数,在实例化时做一些类的初始化工作,self是每次实例化d1或者d2那个内存空间,就是实例本身 self.name = name #实例变量(静态属性) def bulk(self): #类的方法,功能(动态属性),这里的self也是表示实例化的本身,因为要调用相关的内存空间 print("%s wang wang wang!" %self.name) #d1 = Dog("test1")此时self相当于d1,Dog(d1,"test1") d1 = Dog("test1") #Dog类的实例,代表吧d1.test1传给了Dog类,这样子self就是d1本身 d2 = Dog("test2") #生成一个实例,会自动把参数穿个Dog下的__init__(.....) d1.bulk() #只有经过实例化后,才能调用类中的方法 d2.bulk()
2、类的3大特性
2.1、封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
其实就是使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容
2.2、继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
class People(object): def __init__(self,name,age): self.name = name self.age = age def eat(self): print("%s is eating.." %self.name) def talk(self): print("%s is talking..." %self.name) def sleep(self): print("%s is sleeping.." %self.name)
class Relation(object): def make_friends(self,obj): print("%s is making friends with %s " %(self.name,obj.name)) class Man(People,Relation): def __init__(self,name,age,money): super(Man,self).__init__(name,age) #广式继承父类的相关属性,不用自己再声明了,父类已经声明好了 self.money = money #父类中没有的属性,再进行声明 print("%s 一出生就有 %s" %(self.name,self.money)) def piao(self): print("%s is piaoing ..... 20s... done" %self.name) def sleep(self): #如果这里有的话,就不会执行父类的方法,这叫重构父类方法 People.sleep(self) #先继承了父类的方法 print("man is sleeping") class Woman(People): #Woman类完全继承了People中的静态属性,没有对静态属性进行重构 def get_birth(self): #新加了方法 print(“%s is born a baby” %self.name) m1 = Man("test1",'18',100000) #必须传入三个参数 m1.eat() #其实调用了父类的中方法 m1.sleep() #调用的是自己中的方法,只不过继承了父类的方法 w1 = Woman("test2","20") m1.make_friends(w1) #因为上边的m1继承了Relation类,make_friends中又传入两个参数,一个是类本身和另一个类 这句话的意思是 make_friends(m1,w1) 这样子就不难理解每次写self意义了,还有就是每次实例化为什么写 m1 = Man() 2.3、多态 简单的说就是一种方法,多种形态,多态的目标是实现一个接口的重复利用
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") @staticmethod #静态函数就是和类没有直接关联的,所以animal_talk(self)没用 def animal_talk(obj): obj.talk() class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) # def func(obj): # 一个接口,多种形态 # obj.talk() c1 = Cat('小晴') c1.talk() #标准情况下,可以调用类下自己的方法,所以方法里没有任何参数 d1 = Dog('李磊') Animal.animal_talk(c1) #静态方法中,因为和类没有直接关系,所以可以传入自己定义的参数 Animal.animal_talk(d1)
3、类的特殊方法: 3.1、静态方法,就是类不能直接调用了自己的函数了,和类没有直接关系了,需要传入相应的参数,上边例子已经有了。 3.2、类方法:类方法只能访问类变量,不能访问实例变量
class Dog(object): n = “yun” def __init__(self,name): self.name = name @classmethod def eat(self): print("%s is eating %s" %(self.n,'flood')) d = Dog("Test") d.eat() #d.eat()中执行的结果是:yun is eating flood,而不是Test is eating flood,因为此方法调用不了实例的参数,只能调类中的yun
3.3、属性方法: 将类中的方法变为类的属性,调用的时候,只能用f.flight_status 而不能用 f.flight_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("747") f.flight_status
此时遇到有一个问题,不能对类的属性进行赋值,比如你想f.flight_status = 2,是不允许进行直接赋值的,如果想直接赋值,需要加装饰器: @flight_status.setter @flight_status.deleter 如下:
@flight_status.setter #修改 def flight_status(self,status): status_dic = { 0 : "canceled", 1 :"arrived", 2 : "departured" } print("\033[31;1mHas changed the flight status to \033[0m", status_dic[status]) #又get到新的技能,字典可以用get方法,status_dic.get() status_dic.get(status) @flight_status.deleter #删除 def flight_status(self): print("status got removed...") f = Flight("CF747") f.flight_status f.flight_status = 2 del f.flight_status f.flight_status 3.4、反射:通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法 # #### 检查是否含有成员 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 获取成员 #### getattr(obj, 'name') getattr(obj, 'func') # #### 设置成员 #### setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 #### delattr(obj, 'name') delattr(obj, 'func')
def bulk(self): print("%s is yelling..." %self.name) class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating..."%self.name,food) d = Dog("NiuHanYang") choice = input(">>:").strip() #此处 if hasattr(d,choice): #假如有这个属性 delattr(d,choice) #删除方法需要输入eat() fun = getattr(d,choice) #输入的是eat,choice就是eat中的food这个参数,这是对方法的处理 fun("2018") #赋值的相当于是eat中的food attr = getattr(d,choice) setattr(d,choice,"33") #这是对类中的属性进行修改 print(d.age) else: setattr(d,choice,bulk) #把外部的函数装到类里边,此时bulk会变成choice中输入的字符,比如输入talk d.talk(d) # setattr(d,choice,22) #动态属性的添加 # print(getattr(d,choice)) # print(d.name)
4、异常处理 在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面。
def bulk(self): print("%s is yelling..." %self.name) class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating..."%self.name,food) # d = Dog("NiuHanYang") # choice = input(">>:").strip() # getattr(d,choice) data = {} names = [1,2] try: #程序正常就正常执行 # names[3] # data['name'] open("tes.txt") # a = 1 # print(a) # except Exception as e: # print("出错了",e) except (KeyError,IndexError) as e: #具体的错误类型 print("没有这个key",e) except IndexError as e: print("列表操作错误",e) except Exception as e: #不管是什么错误类型 print("未知错误",e) else: # #主代码块执行完,执行该块 print("一切正常") finally: # 无论异常与否,最终执行该块 print("不管有没有错都执行")