面向对象编程:
世界万物,皆可分类
世界万物,对象
只要是对象,就肯定属于某种品类
只要是对象,就肯定有属性
oop编程利用"类"和"对象"来创建各种模型来实现对真实世界的描述,使用面向对象对象编程原因之一是它可以使程序的维护和扩展变得简单,且可以大大提高程序的开发效率,另外,基于面向对象的程序可以使他人更加容易理解你的代码逻辑,从而使团队开发变得从容。
面向对象的核心特性:
1.class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图原型。在类中定义了这些对象的都具备的属性、共同的方法。
class Dog: def __init__(self,name,age): self.name = name self.age = age def bark(self): print("%s: wang wang wang!"%self.name)‘‘‘name、age是静态属性简称属性bark()是动态属性简称方法‘‘‘
2.object 对象(也可以称之为实例)
一个对象即是一个类的实例化后的实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦有不同的属性,就像人类指所有人,每个人指具体的对象,人与人之间有共性,亦有不同
class Dog: def __init__(self,name,age): self.name = name self.age = age def bark(self): print("%s: wang wang wang!"%self.name) d1 = Dog("Alex") d2 = Dog("San Pao") d3 = Dog("San San")‘‘‘d1、d2、d3即实例:把一个类变成一个具体的对象的过程就叫实例化‘‘‘
3.Encapsulation 封装
在类中对数据的赋值、内部的调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含了类的数据和方法,把一些功能的实现细节不对外暴露
4.Inheritance 继承 (组合:用来关联其他对象)
一个类可以派生出子类·,在这个父类里定义的公有属性、公有方法自动被子类继承
python2 经典类是按照深度优先来继承的,新式类是按照广度优先来继承的
python3 经典类和新式类都是统一按照广度优先来继承的
#class People: #经典类 class People(object): #新式类 def __init__(self,name,age): self.name = name self.age = age self.friends = [] def eat(self): print("%s is eating..."%self.name) def sleep(self): print("%s is sleeping...."%self.name) def talk(self): print("%s is talking...."%self.name) class Relation(object): def make_friends(self,obj): print("%s is making friend with %s"%(self.name,obj.name)) self.friends.append(obj) class Man(People,Relation): def __init__(self,name,age,money): ‘‘‘重构父类的构造方法‘‘‘ #People.__init__(self,name,age)#经典类写法 super(Man, self).__init__(name,age)#新式类写法 self.money = 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,Relation): def get_birth(self): print("%s is born a baby......"%self.name) m1 = Man("Mr Wu",19,10000) w1 = Woman("Bai Zao",20) m1.make_friends(w1) print(m1.friends[0].name) #---output----- #Mr Wu is making friend with Bai Zao #Bai Zao
5.Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中衍生出了不同的子类,且每个子类中在继承了同样的方法名是又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
多态性是允许你将对象设置成为和一个或更多的它的子对象相等的技术,赋值之后,父对象就可以根据当前给它的子对象的特性以不同的方式运作。简单地说:允许子类型的指针赋值给父类类型的指针。
那么多态的作用是什么呢?
我们知道,封装可以隐藏实现细节,是代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了---代码重用!。而多态是为了实现另一个目的---接口重用!多态的作用,就是为了在继承和派生的时候,保证使用“家谱”中的任一类的实例的某一属性时的正确调用。
python不支持多态,但可以间接调用。
class Animal(object): def __init__(self,name): self.name = name def talk(self): passclass Cat(Animal): def talk(self): print(‘Meow!‘) class Dog(Animal): def talk(self): print(‘woof! woof!‘) def animal_talk(obj): obj.talk() d1 = Dog("San Pao") c1 = Cat("Li Si") animal_talk(d1) animal_talk(c1) #----output----- #Meow! #woof! woof!
面向对象初级语法:
1.属性:构造函数中定义的变量是静态属性简称为属性
类中定义的函数是动态属性简称为方法
2.类变量(大家共用的属性,可以节省开销)、实例变量
类变量定义:在构造函数和其他函数之外定义的变量就叫类变量
实例变量:在构造函数或实例中定义的变量
class Role(object): n = 123 #类变量 name = "我是类name" #类变量 def __init__(self,name,role,weapon,life_value=100,money=15000): #构造函数 #在实例化时做一些类的初始化的工作 self.name = name #self.name中的name和构造函数的参数name没有任何关系,它们两个一样, #只不过是一种起巧合 self.role = role #实例变量(静态属性),作用域是实例本身 self.weapon = weapon self.money = money def shot(self): #类的方法,功能(动态属性) print("shooting.....") def get_shot(self): print("an....,i got shot....") def buy_gun(self,gun_name): print("%s just bought %s"%(self.name,gun_name)) print(Role)#<class ‘__main__.Role‘> print(Role.n) #123 r1 = Role("Alex","police","AK47") r2 = Role("Jack","terrorist","B22") #实例变量与类变量的优先级 print(r1.n,r1.name) # 123 Alex,故实例变量优先于类变量 #修改实例变量 r1.name = "Mr Wu" print(r1.name)# Mr Wu #删除实例变量 del r1.weapon #添加实例变量 r1.bullet_prove = True #修改类变量(列表、字典例外,无论在哪儿修改都会影响全部实例) r1.n = "改类变量" #这是在r1的内存中创建了一个新的变量n,并没有修改类变量 print("r1:",r1.n,",","r2:",r2.n) #------output------ #r1: 改类变量 , r2: 123 Role.n = "ABC" print("r1:",r1.n,",","r2:",r2.n) #-------output------ #r1: 改类变量 , r2: ABC
3.构造函数:
在实例化的时候做一些初始化工作
def __init__(self,name,age): self.name = name self.age = age
实例化过程:
4.析构函数
在实例释放、销毁的时候自动执行,通常用于做一些收尾工作,如关闭一些数据库连接、临时打开的文件
def __del__(self): #析构函数 print("%s 彻底死了......"%self.name)
5.私有方法、私有属性
在属性、方法前加__即可
例如:
class Dog(object): def __init__(self,name): self.__name = name def __eat(self): pass d = Dog("Da Nao") d.__name #error d.__eat() #error
面向对象高级语法:
1.静态方法、类方法、属性方法
(1)静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性和方法
class Dog(object): def __init__(self,name): self.name = name @staticmethod #静态方法,实际上跟类没什么关系了 def eat(): print("%s is eating %s"%(self.name,"dd")) #error #print("dddd is eating dd ") #ok d = Dog("陈荣华") d.eat() #Name Error:name ‘selif‘ is not defined
(2)类方法:只能访问类变量,不能访问实例变量
class Dog(object): name = "Mr Wu" def __init__(self,name): self.name = name @classmethod #类方法, def eat(cls): print("【\033[1;35m%s\033[0m】 \033[1;38mis eating\033[0m 【\033[1;33m%s\033[0m】"%(cls.name,"鸡排")) d = Dog("dddddd") d.eat() #【Mr Wu】 is eating 【鸡排】
(3)属性方法:把一个方法变成一个静态属性,对用户隐藏实现细节(对用户来说,只需要调用属性即可,无需关心其内部如何操作)
class Dog(object): def __init__(self,name): self.name = name self.__food = None @property #属性方法 def eat(self): #不能添加其他参数 print("%s is eating %s"%(self.name,self.__food)) @eat.setter #给一个属性赋值 def eat(self,food): self.__food = food #print("set to food:",food) @eat.deleter #删除属性方法 def eat(self): del self.__food print("删完了") d = Dog("chenronghua") d.eat #chenronghua is eating None d.eat = "baozi" d.eat #chenronghua is eating baozi del d.eat #删完了 #d.eat #error
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status"%self.flight_name) return 2 @property def flight_status(self): status = self.checking_status() if status == 0: print("\033[1;33m flight got canceled.....\033[0m") elif status == 1: print("\033[1;34m flight is arrived....\033[0m") elif status == 2: print("\033[1;35m flight has departured already....\033[0m") else: print("\033[1;36m cannot confirm the flight status...\033[0m") @flight_status.setter def flight_status(self,status): print("flight %s has changed status to %s"%(self.flight_name,status)) f = Flight("CA980") f.flight_status f.flight_status = 1 ‘‘‘output‘‘‘ ‘‘‘ checking flight CA980 status flight has departured already.... flight CA980 has changed status to 1 ‘‘‘
2.类的特殊成员方法
(1)__doc__:表示类的描述信息
class People(object): ‘‘‘this is the description of People‘‘‘ def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("%s is eating...."%self.name) def piao(self): print("%s is piaoing..."%self.name) print(People.__doc__) #this is the description of People
(2)__module__、__class__
__module__ 表示当前操作的对象在哪个模块
__class__ 表示当前操作的对象的类是什么
class People(object): ‘‘‘this is the description of People‘‘‘ def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("%s is eating...."%self.name) def piao(self): print("%s is piaoing..."%self.name) man = People("dog","male",19) print(man.__module__) print(man.__class__) #output #__main__ #<class ‘__main__.People‘>
(3)__init__
构造方法,通过类创建对象时,自动触发进行(做一些初始化工作)
程序:略
(4)__call__:对象后面加括号,触发执行
class People(object): ‘‘‘this is the description of People‘‘‘ def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("%s is eating...."%self.name) def piao(self): print("%s is piaoing..."%self.name) def __call__(self, *args, **kwargs): print("My name is Mr Wu") man = People("dog","male",19) man() #My name is Mr Wu
(5)__dict__:查看类或对象中的所有成员
class People(object): ‘‘‘this is the description of People‘‘‘ def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("%s is eating...."%self.name) def piao(self): print("%s is piaoing..."%self.name) def __call__(self, *args, **kwargs): print("My name is Mr Wu") man = People("dog","male",19) print(People.__dict__) ‘‘‘ {‘__weakref__‘: <attribute ‘__weakref__‘ of ‘People‘ objects>, ‘__doc__‘: ‘this is the description of People‘, ‘__dict__‘: <attribute ‘__dict__‘ of ‘People‘ objects>, ‘__init__‘: <function People.__init__ at 0x006D6030>, ‘__call__‘: <function People.__call__ at 0x006D6108>, ‘__module__‘: ‘__main__‘, ‘eat‘: <function People.eat at 0x006D6078>, ‘piao‘: <function People.piao at 0x006D60C0>} ‘‘‘
(6)__str__:如果一个类定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
class People(object): ‘‘‘this is the description of People‘‘‘ def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age def eat(self): print("%s is eating...."%self.name) def piao(self): print("%s is piaoing..."%self.name) def __call__(self, *args, **kwargs): print("My name is Mr Wu") def __str__(self): return "hello world" man = People("dog","male",19) print(man) #hello world
(8)__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别是获取、设置、删除数据
程序:略
(9)__new__、__metaclass__:类的创建过程、定制类
预备知识:
‘‘‘ python中一切皆对象,Foo类本身也是一个对象 f对象是通过执行Foo类的构造方法创建. Foo类对象也是通过执行type类的构造方法创建 我们称呼type为类的类或源类 ‘‘‘ class Foo(object): def __init__(self,name): self.name = name f = Foo("alex") print(type(f))#<class ‘__main__.Foo‘> print(type(Foo))#<class ‘type‘>
*******创建类的两种方式*******
#a).普通方式 class Foo(object): def func(self): print("hello alex!") #b).特殊方式 def __init__(self,name,age): self.name = name self.age = age def func(self): print("hello %s!"%self.name) Foo = type("Foo",(object,),{"say":func,"__init__":__init__}) #type第一个参数:类名(传入字符串) #type第二个参数:当前类的基类(传入元组) #type第三个参数:类的成员(传入字典) f = Foo("Mr Wu",19) f.say()#hello Mr Wu! print(f.name)#Mr Wu print(type(Foo))#<class ‘type‘
type类是如何实现的创建类?类又是如何创建对象?
答:类中有一个属性:__mataclass__,其用来表示该类有谁来实例化创建,所以我们可以为__metaclass__设置一个type类的派生类,从而查看类的创建过程
class MyType(type): def __init__(self,what,bases=None,dict=None): print("--MyType init---") super(MyType,self).__init__(what,bases,dict) def __call__(self, *args, **kwargs): print("--MyType call---") obj = self.__new__(self,*args,**kwargs) self.__init__(obj,*args,**kwargs) class Foo(object): __metaclass__ = MyType def __init__(self,name): print("Foo ---init__") def __new__(cls, *args, **kwargs): print("Foo ---new--") return object.__new__(cls) #继承父亲的__new__方法 obj = Foo("alex") ‘‘‘ ------output----- Foo ---new-- Foo ---init__ 原因: 在实例化的时候,首先调用__new__(),再将__new__()的结果传给__init__()完成实例创建, 故 __new__()是用来创建实例的 ‘‘‘
原文地址:https://www.cnblogs.com/BUPT-MrWu/p/9824542.html