python基础——面向对象
来源:互联网 发布:js cookie 永不过期 编辑:程序博客网 时间:2024/06/08 00:05
类中关于self的解析
class Role(object): n=123#类变量 def __init__(self,name,role,weapon,life_value=100,money=15000): #构造函数,在实例化时做一些类的初始化工作 #此处的self是为了传递变量r1、r2之类的,内部实现实例化的时候是把r1和其他的实参一样当做参数传递进来的,所以在这个地方必须有个形参self,否则参数就不匹配了,我们的 #实例化传递的参数是存储在门牌号为r1的内存中的,而下面的这些函数则是存储在类的内存中的,下面的函数中之所以要有self是为了辨别是哪个变量(类似于r1)在调用它 #它的内部实现是:Role.shot(r1),因为shot是存储在类的内存中的,将r1传递进去底部会对它进行处理,才能实现r1.shot()(等价于Role.shot(r1)) self.name = name#赋给了实例,被称为实例变量(静态属性),作用域就是实例本身 self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self):#类的方法,功能(动态属性) print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gunname): print("%s just bought %s"%(self.name,gunname))r1 = Role('Alex','police',"AK47") #生成一个角色,把一个类变成一个具体对象的过程叫实例化,对象也称为Role的实例r2 = Role('Jack','terrorist',"B22") #生成一个角色r1.buy_gun("AK47")
注意:self的用处有两个,第一可以初始化赋值不至于在类里面其他函数里面调用类似于变量name的时候被销毁了,第二可以使之可以调用类里面的函数。这些功能都是在python底部实现的。
类变量与实例变量
class Role(object): n=123#类变量 name="类name"#类变量 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name#实例变量 self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gunname): print("%s just bought %s"%(self.name,gunname))r1 = Role('Alex','police',"AK47") #在类外增加删除属性r1.bullet_prove=True#可以给r1对象增加一个属性,r2不拥有,因为它仅仅是存储在对象r1的内存中的del r1.name#也可以删除一个r1对象的属性,r2对象依然用于name属性,它删除的也只是存储在对象r1内存中的r2 = Role('Jack','terrorist',"B22") r1.buy_gun("AK47")#类变量print(r1.name)#打印Alex,它会现在实例变量中找,如果找不到则到类变量中找print(Role.n)#打印123,因为存储在类内存中,所以可以直接调用print(r1.n)#打印123,底层将r1传递进去了,可以直接调用(底层实现的)r1.n="修改类变量"print(r1.n)#打印出“修改类变量”,修改类变量相当于在对象的内存中增加了一个与类变量一样的属性,类内存中的变量实质上并没有任何改变,而当跟类变量属性相同时,先找对象内存中的print(r2.n)#打印123,通过对象改变类变量并不会真正的改变类变量,而r2中之前没有这个属性,所以会直接找类内存中的Role.n="通过类修改了类变量"print(r1.n)#打印“修改类变量”,因为上面的r1.n="修改类变量"相当于已经给它增加了一个同类变量n相同的属性,所以它会想找对象内存中的,所以打印出“修改类变量”print(r2.n)#打印“通过类修改了类变量”,因为r2对象内存中并没有n这个属性,所以会到类内存中去找
类变量是对象共用的属性(东西,n都是一样的),能够节省开销(我们在构造函数中定义一个默认参数n也可以实现,但是每次都要初始化并在不同的对象中都得给它分配一个内存),而实例变量则是对象各自独有的属性(nam、role等传递进去的不同,也就不一样了)。当我们个别对象有些特例外,我们在外面也可以通过对象进行修改(实质上是定义一个同类变量一样的属性而已)。
私有属性和方法
class Role(object): n=123#类变量 name="类name"#类变量 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name#实例变量 self.role = role self.weapon = weapon self.__life_value = life_value#__life_value前面加了两个横线就变成了私有属性,私有属性只能在类内部访问,外部访问不了 self.money = money def getPrivate(self): print("the life is:%s"%self.__life_value)#正确,这是在类的内部 def shot(self): print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gunname): print("%s just bought %s"%(self.name,gunname))r1 = Role('Alex','police',"AK47")#在类外增加删除属性r1.buy_gun("Ak47")r1.got_shot()#print(r1.__life_value)#错误,这是在类的外部,访问不了r1.getPrivate()
析构函数
析构函数的作用:在实例释放、销毁的时候自动执行(不需要调用,只需要写一个析构函数即可),通常用于一些收尾工作,如关闭一些数据库链接、打开的临时文件
class Role(object): n=123#类变量 name="类name"#类变量 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name#实例变量 self.role = role self.weapon = weapon self.life_value = life_value self.money = money def __del__(self):#析构函数 print("%s彻底挂了……"%self.name) def shot(self): print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gunname): print("%s just bought %s"%(self.name,gunname))r1 = Role('Alex','police',"AK47")#在类外增加删除属性r1.buy_gun("Ak47")r1.got_shot()del r1.namedel r1#手动删除对象的时候,它会调用析构函数,否则它只会在对象释放的时候或在程序结束的时候调用,只有在删除对象的时候才会调用析构函数,删除一个属性的时候不会调用析构函数r2 = Role('Jack','terrorist',"B22")r2.buy_gun("BBS")
继承
class People: def __init__(self,name,age): self.name=name self.age=age 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 Man(People):#class Man(People) Man类继承People类 passm1=Man("Jorocco",22)#此处必须传递两个参数,即使Man类中没有其他的属性,原因是:继承的People类中有传递参数,所以此处传递的参数不仅仅涉及到Man类自身的参数,还要考虑父类的参数,因为父类的构造函数有两个参数,这里的构造函数是继承的父类,因为子类它本身,没有构造函数m1.eat()'''class Man(People): def piao(self): print("%s game over……20s"% self.name)#这里之所以可以直接self.name,是因为继承了父类People,父类People有name属性 ''' def sleep(self): print("man is sleeping")#名字与父类方法名相同,这是重写父类的方法 ''' #在父类的基础方法的基础上添加新的功能,即重构 def sleep(self): People.sleep(self)#先执行父类的方法 print("man is sleeping")m1=Man("Jorocco",22)#此处必须传递两个参数,即使Man类中没有其他的属性,原因是:继承的People类中有传递参数,所以此处传递的参数不仅仅涉及到Man类自身的参数,还要考虑父类的参数,因为父类的构造函数有两个参数,这里的构造函数是继承的父类,因为子类它本身,没有构造函数m1.eat()m1.piao()m1.sleep()
继承之经典类与新式类
#class People:#经典类class People(object):#新式类,super和这个是配套的,super也是新式写法 def __init__(self,name,age): self.name=name self.age=age 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 Man(People):#class Man(People) Man类继承People类 def __init__(self,name,age,money):#当需要给子类在初始化的时候加个属性,则父类的形参属性也需要被传进来 #People.__init__(self,name,age)#并且需要先调用父类的构造函数进行先初始化,经典写法 super(Man,self).__init__(name,age)#这种写法和上面的People.__init__(self,name,age)写法一样的意思 self.money=10#然后再进行初始化子类所特有的属性,其实这也相当于重构 def piao(self): print("%s game over……20s"% self.name)#这里之所以可以直接self.name,是因为继承了父类People,它有name属性 def sleep(self): People.sleep(self)#先执行父类的方法 print("man is sleeping")class Woman(People):#多继承,先执行自己的构造函数,此处它本身没有构造函数,则继承People的构造函数,如果People没有则继承Relation的构造函数,并不是一一继承的 def get_birth(self): print("is born a baby……")m1=Man("Jorocco",22,10)#父类的参数name age以及子类的参数moneyw1=Woman("Morocco",24)m1.make_friends(w1)
super之参数问题
#class People:#经典类class People(object):#新式类,super和这个是配套的,super也是新式写法 def __init__(self,name,age): self.name=name self.age=age 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 friends with %s"%(self.name,obj.name))# class Man(People,Relation):#class Man(People) Man类继承People类# def __init__(self,name,age,money):# super(Man,self).__init__(name,age)#当继承多个父类的时候,这里的参数怎么填?一般这种继承多个父类的时候,我们要么知道它继承的是谁,就填相应的参数# self.money=10 #要么就用组合的方式,意思就是单继承,但是在它的内部调用另一个父类,尽量能知道继承的构造函数,就用那种方式# def piao(self):# print("%s game over……20s"% self.name)# def sleep(self):# People.sleep(self)# print("man is sleeping")# class Woman(People,Relation):# print("is born a baby……")## m=Man("Jorocco",22,10)## w1=Woman("Morocco",24)# m.make_friends(w1)#组合方式class Man1(People):#class Man(People) Man类继承People类 def __init__(self,name,age,money,Relation_obj): super(Man1,self).__init__(name,age)#当继承多个父类的时候,这里的参数怎么填?一般这种继承多个父类的时候,我们要么知道它继承的是谁,就填相应的参数 self.money=10 #要么就用组合的方式,意思就是单继承,但是在它的内部调用另一个父类 self.relation=Relation_obj def piao(self): print("%s game over……20s"% self.name) def sleep(self): People.sleep(self) print("man is sleeping") def make_friends(self,obj):#要么就用组合的方式,意思就是单继承,但是在它的内部调用另一个父类 self.relation.make_friends(obj)class Woman(People,Relation): print("is born a baby……")relation_obj=Relation()m1=Man1("Jorocco",22,10,relation_obj)w1=Woman("Morocco",23)m1.make_friends(w1)
python构造函数的继承顺序
python3的经典类和新式类继承都是广度优先策略的,python2的经典是按深度优先来继承的,新式类是按广度优先来继承的
class A: def __init__(self): print("A")class B(A):#B继承A def __init__(self): print("B")class C(A):#C继承A def __init__(self): print("C")#若D中没有构造函数,则找B,若B中也没有构造函数,则再找C,C中也没有则找A,它并不是我们惯性认为的一一继承,为此当我们实例化传递参数的时候需要注意考虑它是如何继承的,因为需要根据它继承的方式进行相应的参数传递class D(B,C):#从左到右进行继承的,即先继承B再继承C passobj=D()
多继承(同级父类调用它自身没有的属性)
class People(object):#新式类,super和这个是配套的,super也是新式写法 def __init__(self,name,age): self.name=name self.age=age 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 __init__(self,money): self.money=money def make_friends(self,obj):#这里之所以可以直接self.name,obj.name,是因为函数只有在调用的时候才执行的,比如此处只有在程序执行m1.make_friends(w1)的时候函数才被调用执行,在这之前我们都已经初始化完了,初始化了self.name,obj.name这个就合法了,因为子类有了这些属性(继承自父类的)。#初始化的时候是按广度优先进行继承的,先继承自左父类(People)的构造函数,如果有,则继承(继承完了不继承后面的),没有则继承右父类(Relation)#当继承了左父类的构造函数时,self.name已经被初始化了,对象obj(w1)也已经被初始化了,所以obj.name也合法#如果写成class Woman(Relatio,People),则先继承Relatio的构造函数,但它没有构造函数,则再找People的构造函数,在这个地方也不会出错#若是Relatio有构造函数,且初始化时没有name属性(self.name),则在此调用则会报错,正如位置1展示的那样 print("%s is making friends with %s"%(self.name,obj.name))#如果是位置1则报错,因为调用的构造函数是Relation的,但是它并没有name这个属性,obj.name不会出错,因为它初始化继承的是People,People有name属性 #如果是位置2则不会报错,People有name属性#class Man(Relation,People):#位置1class Man(People,Relation):#位置2 def piao(self): print("%s game over……20s"% self.name)#这里之所以可以直接self.name,是因为继承了父类People,它有name属性 def sleep(self): People.sleep(self)#先执行父类的方法 print("man is sleeping")class Woman(People): def get_birth(self): print("is born a baby……")#m1=Man(10)#位置1 此处的参数我们要看继承的是哪个构造函数,然后再视其构造函数的参数进行给予,比如:此处我们继承的是Relation,它的构造函数只有一个参数,所以此处只能传递一个参数m1=Man("Jorocco",23)#位置2 位置2调用的是People的构造函数,它的参数是两个,所以此处只需给予两个w1=Woman("Morocco",24)m1.make_friends(w1)
多态
#多态:一种接口,多种实现,实现接口的重用class Animal(object): def __init__(self, name): # Constructor of the class self.name = name @staticmethod def animal_talk(self): # Abstract method, defined by convention only self.talk()class Cat(Animal): def talk(self): print('%s: 喵喵喵!' %self.name)class Dog(Animal): def talk(obj): print('%s: 汪!汪!汪!' %obj.name)#方法1实现的多态# def func(obj): #一个接口,多种形态 方法1# obj.talk()## c1 = Cat('小晴')# d1 = Dog('李磊')## func(c1)#都是接口func,实现了不同的功能# func(d1)#都是接口func,实现了不同的功能,这就是多态#方法2实现的多态,规范的,一种接口多种实现c1 = Cat('小晴')d1 = Dog('李磊')Animal.animal_talk(c1)Animal.animal_talk(d1)
类方法
class Dog(object): n=122 def __init__(self,name): self.name=name @classmethod#类方法只能访问类变量,不能访问实例变量 def eat(self,food): print("%s is eating %s"%(self.n,food))#n是类变量所以可以访问 #print("%s is eating %s"%(self.name,food))#错误,name是实例变量,不能访问d=Dog("Jorocco")d.eat("馒头")
静态方法
class Dog(object): def __init__(self,name): self.name=name @staticmethod#只是名义上归类管理,实际上跟类没什么关系了,实际上在静态方法里访问不了类或实例中的任何属性 def eat(self,food): print("%s is eating %s"%(self.name,food))#这样是错误的,因为它不会将对象本身传到类里头,所以下面的那个"馒头"只是给了self,这个food并没有参数与之匹配,少了一参数,而且self.name会报错d=Dog("Jorocco")d.eat("馒头")
属性方法
class Dog(object): n=122 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): print("set to food:",food) self.__food=food #位置2 @eat.deleter def eat(self): del self.__food print("删完了")d=Dog("Jorocco")d.eat#调用的是 @property方法d.eat="馒头"#调用的是 @eat.setter方法del d.eat#如果没有位置2,直接删除则会报错
属性方法之赋值
class Dog(object): n=122 def __init__(self,name): self.name=name @property#属性方法,把一个方法变成一个静态属性 def eat(self,food): print("%s is eating %s"%(self.name,food)) #位置2 加了这个之后的 @eat.setter def eat(self,food): print("%s is eating %s"%(self.name,food))d=Dog("Jorocco")#这种赋值都是错误的#d.eat("馒头")#错误,它已经变成一个属性了,不能调用方法#d.eat="馒头"#错误d.eat="馒头"#加了位置1的赋值 才正确
属性方法之删除
class Dog(object): n=122 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): print("set to food:",food) self.__food=food #位置2 @eat.deleter def eat(self): del self.__food print("删完了")d=Dog("Jorocco")d.eat#调用的是 @property方法d.eat="馒头"#调用的是 @eat.setter方法del d.eat#如果没有位置2,直接删除则会报错
阅读全文
0 0
- python基础—面向对象
- python——面向对象基础
- python基础——面向对象
- Python基础进阶篇——面向对象编程基础
- Python面向对象基础
- python面向对象基础
- python 面向对象基础
- python面向对象基础
- python 面向对象 基础
- Python基础-面向对象基础
- Python——11面向对象编程基础
- python第六天学习记录——面向对象基础
- python面向对象编程基础
- Python 基础08 面向对象
- Python基础08 面向对象
- Python面向对象编程基础
- Python面向对象编程基础
- python面向对象编程基础
- 查看linux内核模块依赖关系的三种方法
- Webuploader 上传图片与form表单(二)
- python: time模块、datetime模块
- 进程的基本状态
- 十进制与二进制相互转换(包括带小数点)
- python基础——面向对象
- 代码整洁_迭进
- Codeforces 846 B MAth Show
- 移植程序步骤及注意点(keil5)
- Python学习笔记day05
- Numpy学习笔记——矩阵和通用函数
- 基于SRAM的内存管理
- 进程和线程定义,概念,区别详解
- ASP.NET MVC上传文件