目录 类的数据属性 实例属性 #旧式类,经典类 #新式类(和继承有关),object是父类 主要应用在pyhton3中 #一般行数比较多,不建议使用交互方式编辑 类定义练习 类属性之继承 '''子类具有父类的所有属性和方法 ''' #类的多态 -*- coding: utf-8 -*- 回顾类的三大属性: #类属性的 获取机制 -*- coding: utf-8 -*- 类属性保存于类中,实例化属性保存于相应的实例中 类方法定义与调用实例: @classmethod 类的静态方法 @staticmethod 类的方法 只访问 类属性 实例方法 即访问实例属性,也可以访问类属性 静态方法 两个属性均不访问 类方法的重写,针对父类的方法不能满足子类的需求 '''子类具有父类的所有属性和方法 ''' ''' 子类重写父类的方法,重新调用时会调用子类的方法,而不是父类的方法''' 1. is 判断的是对象是不是同一个,标准是两个标识符所表示的 对象在内存中的空间是否一致 a is b 等同于 id(a)==id(b) 注意,判断none时建议使用is进行判断 2. 私有属性 #私有属性不能够在外部被直接访问 #私有方法同样不能在外不被直接访问 父类私有属性和方法 子类不能直接调用, 类多继承: __new__练习 类的数据属性 实例属性class A: x=7 #l类属性,静态数据 def __init__(self,a): self.x=a #实例化属性 aa=A() print(A.x) #实例属性更新了,类属性不会改变 print(aa.x) aa.x=1 print(A.x) print(aa.x)
‘’’ 7 77 7 1 ‘’’ |
#旧式类,经典类class A: ''' this is A ''' pass #实例化 a=A() print(type(a)) print(type(A)) print(a.__class__) #显示类型 print(a.__doc__)#显示类文档
‘’’
this is A ‘’’ |
#新式类(和继承有关),object是父类 主要应用在pyhton3中class B(object):#约定俗称 类的首字母大写 #构造函数,实现类初始化 def __init__(self): pass b=B() print(type(b)) print(type(B)) |
#一般行数比较多,不建议使用交互方式编辑class People(object): #构造函数,实现初始化 #self 当前的类 Name='CCTV' #赋值,为初始化则赋值,做了初始化就没有赋值了(不建议这么使用,放在初始化函数中职能分工会更加明确) #真正意义上的构造函数 def __new__(cls, *args, **kwargs): return object.__new__(cls, *args, **kwargs)
def __init__(self,Name,Sex,Age): #初始化函数 self.Name='name' self.Sex='sex' self.Age='age' print(self) pass
fbb=People('fbb','female','32') print(fbb) print(fbb.Name)#就像是填表,表示一个类,通过填表的过程类进行了实例化,表格也从类变成了一个对象 |
类定义练习class 类名(大驼峰): def 方法1(self,参数列表): pass def 方法2(self,参数列表): pass
实例对象=类() class Cat: def eat(self): print('%s爱吃鱼'%self.name) def drink(self): print('爱喝水') |
lazy_cat=Cat() lazy_cat.name='lazy_cat' lazy_cat.eat() lazy_cat.drink() print(lazy_cat) addr1=id(lazy_cat) print(addr1)
lazy_cat2=lazy_cat #内存中地址相同 print(lazy_cat2) addr2=id(lazy_cat2) print(addr2)
print(lazy_cat.name) |
class Person: def __init__(self,name,weight): self.name=name self.weight=weight print('创建实例化对象',self.name) def run(self): self.weight=self.weight-0.5 print(self.weight,'Kg') def eat(self): self.weight=self.weight+1 print(self.weight,'Kg') def __str__(self): return 'name=%s'%self.name+' weight=%s Kg'%self.weight def __del__(self): print('实例化对象%s已被清除'%self.name) xiaoming=Person('xiaoming',70) xiaomei=Person('xiaomei',45) xiaoming.run() xiaoming.eat() print(xiaoming) print(xiaomei) |
#房屋面积 class House: def __init__(self,housetype,Total_Area,Free_Area=None,House_Item=[]): self.House_Type=housetype self.Total_Area=Total_Area self.Free_Area=Total_Area self.House_Item=House_Item print(self.House_Type,self.Total_Area, self.Free_Area,self.House_Item) # def __del__(self): # print('删除格式化对象',self) def __str__(self): print(self.House_Type,self.Total_Area, self.Free_Area,self.House_Item) return ' ' def add_list(self,House_Item): self.House_Item.append(House_Item.HouseItem_type) self.Free_Area-=House_Item.HouseItem_Area print('add',House_Item.HouseItem_type,'free_area=',self.Free_Area) # Free_Area=Free_Area-????
class HouseItem: def __init__(self,HouseItem_type,HouseItem_Area): self.HouseItem_type=HouseItem_type self.HouseItem_Area=HouseItem_Area print(self.HouseItem_type,self.HouseItem_Area) def __del__(self): print('删除格式化对象',self) def __str__(self): print(self.HouseItem_type,self.HouseItem_Area)
XjHouse=House('三室一厅',100,100) bed=HouseItem('席梦思bed',4) chest=HouseItem('衣柜chest',2) table=HouseItem('餐桌table',1.5)
XjHouse.add_list(bed) XjHouse.add_list(chest) XjHouse.add_list(table)
print(XjHouse) |
类属性之继承class Animal: def eat(self): print('吃东西喽') def drink(self): print('喝水水') def run(self): print('跑了跑了') def sleep(self): print('shuijiao睡觉') class Dog(Animal): def bark(self): print('汪汪叫')
class Xiaotian(Dog): '''子类具有父类的所有属性和方法 '''def fly(self): print('我是一只可以飞的狗狗') xiaohei=Dog()
xiaohei.eat() xiaohei.drink() xiaohei.run() xiaohei.sleep() xiaohei.bark() print('-------------------')
xt=Xiaotian() xt.fly() xt.eat() xt.drink() xt.run() xt.bark() |
#类的多态 -*- coding: utf-8 -*-""" Created on Wed Dec 27 15:30:13 2017 回顾类的三大属性:1. 封装:将属性和方法封装到抽象的类中; 2. 继承:代码重用,减少代码编辑量;设计类的技巧,子类根据自己需求可以便携特定的代码 3. 多态:增加代码的灵活度;以继承和重写父类方法为前提,调用方法的技巧,不会影响类的内部设计 不同的对象 调用同样的方法,会产生不同的结果; @author: 康宁 """ class Dog(object): def __init__(self,name): self.name=name def game(self): print('狗狗在玩耍') def __del__(self): pass
class XiaoTianQuan(Dog): def __init__(self,name): self.name=name def game(self): print('神一般地玩耍。。。') ''' super(XiaoTianQuan,self).game() #super(子类,self)作用是找到子类的父类并将其实例化, 实例化之后调用方法不需用加self Dog.game(self) #如果是这样,Dog表示的是类,并不是实例, 所以在括号中需要加上self ''' super(XiaoTianQuan,self).game() Dog.game(self) def __del__(self): pass
class People(object): def __init__(self,name): self.name=name def play(self,dog): print(self.name,' and ',dog.name,' are playing') dog.game() def __del__(self): pass
xt=XiaoTianQuan('xt') xiaoming=People('xiaoming')
xiaoming.play(xt) Dog.game(1) XiaoTianQuan.game(xt)
|
#类属性的 获取机制 -*- coding: utf-8 -*-类属性保存于类中,实例化属性保存于相应的实例中class Tool(object): count=0 @classmethod def showcount(cls): print('ccount= ',cls.count) def __init__(self,name): self.name=name Tool.count+=1 pass
tool1=Tool('锤子') tool2=Tool('钉子')
tool3=Tool('枕头') ''' 1. 调用类属性可以使用 类名.属性 调用, 2. 也可以使用 实例.类属性名 调用 -----》》》不推荐, 因为容易使用赋值语句,这样就会在相应的 实例中创造一个新实例化属性 '''
print(Tool.count) print(tool1.count) Tool.showcount() |
类方法定义与调用实例:@classmethod#修饰函数,表明下面定义的方法是类方法,不是实例化方法 def showcount(cls): #cls相当于实例化方法中的self,指代调用该类方法的对象,也就是类 print('ccount= ',cls.count) class Tool(object): count=0 @classmethod def showcount(cls): print('ccount= ',cls.count)
def __init__(self,name): self.name=name Tool.count+=1 pass
tool1=Tool('锤子') tool2=Tool('钉子')
tool3=Tool('枕头')
print(Tool.count) print(tool1.count) Tool.showcount() '''类对象Tool调用showcount()类函数,此处不需用传入cls,因为此处Tool类就是该函数的对象 ''' |
类的静态方法
class Dog(object): def __init__(self,name): self.name=name @staticmethoddef run(): print('run run run ')
xiaohei=Dog('xiaohei') xiaohei.run() Dog.run() |
类的方法 只访问 类属性实例方法 即访问实例属性,也可以访问类属性静态方法 两个属性均不访问class Game(object): top_score=0 @classmethod def show_top_score(cls): print('top score is:',cls.top_score)
@staticmethod def help_info(): print('help信息')
def __init__(self,player_name): self.player_name=player_name
def start_game(self): print('game start, come on',self.player_name)
#1. 查看帮助信息 Game.help_info() #2. 差看历史最高分 Game.show_top_score() #3. 开始游戏 ckn=Game('ckn') ckn.start_game() #4. 让僵尸进入大门 |
类方法的重写,针对父类的方法不能满足子类的需求
class Animal: def eat(self): print('吃东西喽') def drink(self): print('喝水水') def run(self): print('跑了跑了') def sleep(self): print('shuijiao睡觉')
class Dog(Animal): def bark(self): print('汪汪叫')
class Xiaotian(Dog): '''子类具有父类的所有属性和方法 '''def fly(self): print('我是一只可以飞的狗狗') def bark(self): ''' 子类重写父类的方法,重新调用时会调用子类的方法,而不是父类的方法'''print("神一般的汪汪叫") '''重写时 父类的同名的方法可以作为子类新方法的组成 部分super().父类方法 or 父类.父类方法(self) 来实现调用''' super().bark() Dog.bark(self)#不建议使用,因为父类名称一旦改变,需要改动的部分比较多 #此处若使用子类,会出现递归调用,没有出口形成死循环 xt=Xiaotian() xt.bark() |
''' 1. is 判断的是对象是不是同一个,标准是两个标识符所表示的对象在内存中的空间是否一致 a is b 等同于 id(a)==id(b)注意,判断none时建议使用is进行判断#c=[1,2,3] #d=[1,2] #print(id(c),id(d)) #d.append(3) #print(id(c),id(d)) #print(c==d) #print(c is d) #print(id(c)==id(d)) ##对于none的匹配或者对比建议使用is #print(a is None) ''' result: 933776315592 933789882504 '''
''' 2. 私有属性#私有属性不能够在外部被直接访问#私有方法同样不能在外不被直接访问''' class Women: def __init__(self,name,age): self.name=name self.__age=age def secret(self): print('secret') print(self.name,self.__age) def __secret0(self): print('__secret0') print(self.name,self.__age)
xiaomei=Women('xiaomei',18) ''' 对象的外部不能直接访问对象的私有属性''' print(xiaomei._Women__age) ''' 对象的内部方法可以访问对象的私有属性''' xiaomei.secret() ''' 对象的内部私有方法不可以被直接访问''' #xiaomei.__secret0() ''' 伪私有,访问方法: _类名__私有属性/私有方法()''' xiaomei._Women__secret0() |
父类私有属性和方法 子类不能直接调用,
1. 子类可以访问父类的公有属性和公有方法,不能直接访问父类的私有属性和私有方法 2. 子类可以通过访问父类的公有方法来间接访问父类的私有属性和私有方法 class A: pass def __init__(self): self.num1=100 self.__num2=200 def test(self): print('父类非私有方法',self.num1,self.__num2) def __test(self): print('父类私有方法',self.num1,self.__num2) class B(A): def demo(self): print('子类的方法',self.num1)#,self.__num2) ''' 子类的方法中不能访问父类的私有属性''' super().test() #子类的方法中中可以访问父类的非私有方法 super().__test() pass b=B() print(b.num1) #print(b.__num2) '''父类的私有属性和私有方法不能在子使用子类直接访问 ''' b.test() #b.__test() b.demo() |
类多继承:class 类名(父类1,父类2,。。。。):: pass 注意: 1.如果多个父类之间存在同名的方法,应该避免多继承; 2. 类名.__mro__指定的搜索顺讯进行执行 class A(object): def test(self): print('A test-----') pass def demo(self): print('A demo-----') pass class B(object): def test(self): print('B test-----') pass def demo(self): print('B demo-----') pass class C(A,B): pass c=C() c.test() c.demo() print(C.__mro__)#注意,是类,不是实例 |
__new__练习1. 只分配第一次创建对象时的内存空间 2.只做一次初始化操作,但是每次构建一个新对象都会调用初始化函数, 经过改造只有第一次调用初始化函数会会执行初始化操作 class MusicPlayer(object): instance=None init_flag=None def __new__(cls,*args,**kargs):#chognxie 重写__new__函数 #1. 创建时会被自动调用, print('创建对象,分配空间') if MusicPlayer.instance is None: MusicPlayer.instance=super().__new__(cls)#???这里不明白为什么要加上cls--->super产生的是实例化对象,不是类对象,所以实例化对象调用类函数需要将类作为参量传入类函数,如果是类对象调用类函数就不需用传cls了 return MusicPlayer.instance ''' super(XiaoTianQuan,self).game() #super(子类,self)作用是找到子类的父类并将其实例化, 实例化之后调用方法不需用加self Dog.game(self) #如果是这样,Dog表示的是类,并不是实例, 所以在括号中需要加上self ''' def __init__(self): if MusicPlayer.init_flag is None: print('播放器初始化') MusicPlayer.init_flag=1 else: return
kuwo=MusicPlayer() print(kuwo)
youku=MusicPlayer() print(youku) |