Python编程学习-基础笔记06
2022/7/12 1:28:43
本文主要是介绍Python编程学习-基础笔记06,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
八、面向对象
8.1 面向对象基础
面向对象:是将一组具有共同特征的事物,将其抽象出来,作为基类,然后再以类为模板去创建具体的对象。比如学生是一个类,而具体到某位同学则是对象,他们具有共同的学生类特征。
8.1.1 类和对象的定义示例:
''' 面向对象: 程序 vs 现实 对象 ----> 具体的事物 现实中事物 --> 转化为程序 : 世间万物皆对象 好处: 类 对象 属性 方法 对象: xxx的手机 对象的集合 --> 共同点: 动作:打电话、发短信、上网.... --> 方法 特征:品牌、颜色、大小、价格... --> 属性 类别:手机类 多个对象 --》 提取对象的共同特征和动作 --》封装到一个类中 ''' #类名要求首字母大写,多个单词用驼峰式 ValueError, #定义类和属性 #定义类 class Student(): #类属性 name = 'jack' age = 10 #使用类来创建对象 对象 = 类名() jack = Student() jack.age = 18 #对象属性 print(jack.age) #先找自己空间的,如果没有,然后再去类中查找 print(jack.name) jack.gender = 'Male'
8.1.2 构造器
类中的方法:动作
''' 类中中的方法:动作, 种类:普通方法(函数),类方法,静态方法,魔术方法 普通方法格式: def 方法名(self,[选填参数]): pass 类方法: class 类名: def 方法名(self): pass ''' # class Phone(): #默认继承object #属性 brand = 'Huawei' price = 5399 type = 'Mate40Pro' #方法 def call(self): #self 获取到的是函数内存地址 print('self---->',self) #self----> <__main__.Phone object at 0x0000023B8DC9A6A0>,基于函数调用而不断变化 print('正在访问通讯录') for person in self.address_book: #phone2没有定义address_book,调用则会报错,这里是不能保证每个self中都存在address_book print(person.items()) print('正在打电话……') print('留言:',self.note) #不能保证每个self中都存在note phone1 = Phone() phone1.note = '我是phone1 的note' phone1.address_book = [{'13888889999':'Jack'},{'13888889991':'Lucy'}] print(phone1.brand) print(phone1,'*****1*****') #<__main__.Phone object at 0x0000023B8DC9A6A0> *****1***** phone1.call() #call(phone1) --> self.note phone2 = Phone() phone2.note = '我是phone2 的note' print(phone2.brand) print(phone2,'******2****') #<__main__.Phone object at 0x0000024314FDA630> *****2***** phone2.call() #call(phone2) --> self.note
8.1.3 初始化对象
在类中定义魔术方法,对象调用时动态改变其参数。
# 类中的方法 class Phone(): #默认继承object #魔术方法之一,称作魔术方法:__名字__() def __init__(self): #初始化 print('----------------init') #动态的给self空间添加2个属性brand 和 price self.brand = 'Huawei' self.price = 3999 def call(self): #self不断发生变化 print('---------->call') print('---------->price:',self.price) #不能保证每个self都有price ''' 1,p先去内存中找有没有一块空间叫Phone; 2,利用Phone类,向内存申请一块跟Phone一样的空间; 3,去Phone中去找方法__init__ 如果没有,则执行将开辟的内存给对象p 如果有,则进入__init__方法,执行里面的动作,这里self得到的地址是p的地址,执行完成后,将地址赋值给对象p ''' p = Phone() # p.price = 3000 #可修改初始值 p.call() #p.call() p是对象 p1 = Phone() p1.call()
8.1.4 对象方法
class Person: name = 'Forrest' # #不带参数 # def __init__(self): #保证每个对象空间都有 name 和age # self.name = 'Lucy' # self.age = 18 #带参数 def __init__(self,name,age): #保证每个对象空间都有 name 和age self.name = name self.age = age #不带参数 # def eat(self): #公共的动作,函数调用才不会有阴影 # print(f'{self.name} is eating Apple') #带参数 def eat(self,food): #公共的动作,函数调用才不会有阴影 print(f'{self.name} is eating {food}') def run(self): #self.gender不是公共动作,pycharm报阴影 print(f'{self.name}正在跑步,{self.age}岁了,性别:{self.gender}') #创建对象p p = Person('唐力',25) #这里传的参数给init p.name = 'Tony' p.eat('Orange') #这个给对应的函数 p.gender = 'Female' p.run() #创建对象p1 p1 = Person('摩卡',18) p1.name = 'Mobi' p1.eat('Peach')
8.1.5 类方法
8.1.5.1 基础方法
''' 类方法 特点: 1,定义需要依赖装饰器@classmethod 2,类方法中的参数不是一个对象,而是类 print(cls) #<class '__main__.Dog'> 这里打印的是Dog类 3,类方法中只可以使用类属性 4,类方法中是否可以使用普通方法? --> 不能 作用: 1,因为只能访问类属性和类方法,所以可以在对象创建之前,如果需要去完成一些动作/功能,可以将器放在类方法中 2,不依赖于对象 ''' class Dog: def __init__(self,nickname): self.nickname = nickname def run(self): # self 对象去调用 print(f'{self.nickname}在院子里跑来跑去……') def eat(self): print(f'{self.nickname} is eating delicious food……') self.run() #类方法中的调用,需要通过 self.func() #装饰器 @classmethod def test(cls): #cls class 类去调用 print(cls) #<class '__main__.Dog'> 这里打印的是Dog类 # print(cls.nickname) # 类里没有定义nickname,报错AttributeError: type object 'Dog' has no attribute 'nickname' d = Dog('Penny') d.run() d.test() #会出错
8.1.5.2 补充方法
''' 类方法:补充方法 ''' class Person: # age = 18 #类里公共的,外部可以访问调用 __age = 18 #加__ 私有化,只能在类内部调用 def show(self): print('---------->',Person.__age) @classmethod def update_age(cls): cls.__age = 20 print('----》类方法') @classmethod def show_age(cls): print('修改后的年龄是:',cls.__age) #直接调用类,不依赖于对象 Person.update_age() Person.show_age()
8.1.6 静态方法
''' 静态方法:类似于类方法 1,需要装饰器 @staticmethod 2,静态方法无须传递任何参数(self,cls) 3,只能访问类的属性和方法,对象的方法无法访问 4,加载时机同类方法 ''' class Person: __age = 18 #加__ 私有化,只能在类内部调用 def __init__(self,name): self.name = name def show(self): print('---------->',Person.__age) @classmethod def update_age(cls): cls.__age = 20 print('----》类方法') @classmethod def show_age(cls): print('修改后的年龄是:',cls.__age) @staticmethod def test(): print('---->静态方法') # print('--->',self.name) #语法错误,没有self print(f'--->',Person.__age) # 只能通过类来调用 #直接调用类,不依赖于对象 Person.update_age() Person.show_age() Person('Jack').test() #调用静态方法
8.1.7 总结
类方法 和 静态方法 不同: 1,装饰器不同 2,参数不同,类方法有参数,静态方法无参数 相同: 1,只能访问类的属性和方法,对象的方法无法访问 2,都可以通过类名访问 3,都可以在创建对象之前使用,因为都不依赖于对象 普通方法与两者的区别 不同: 1,没有装饰器 2,普通方法要依赖于对象,因为每个普通方法都有self,self 表示对象本身 3,只有创建了对象,才可以调用普通方法,否则无法调用
8.2 魔术方法
魔术方法是一个对象/类中的方法,和普通方法的唯一不同是:普通方法需要调用,而魔术方法是在特定的时刻自动触发。
''' 魔术发方法: 1, __init__, 初始化, 触发时机:初始化对象时触发,(不是实例化触发,但是和实例化在一个操作中) 2,__new__ 实例化的魔术方法 触发时机:实例化对象时触发 3,__call__ 对象调用方法 触发时机:把对象当函数调用时触发,会默认调用此函数中的内容 4,__del__虚构魔术方法, delete的 缩写,使用默认,建议不要自己写 触发时机:当对象没有用的时候触发。(没有任何变量引用 ) 1,对象赋值 p = Person('Jack') p1 = p p2 = p 说明:p,p1,p2指向同一个地址 2,删除地址引用 del p2 删除p2对地址的引用 3,查看对地址的引用次数 sys.getrefcount(p) 4,当一块空间没有变量引用,默认执行__del__ 动作, ref = 0 程序运行到最后,也会默认执行__del__ 动作,释放所有的内存占用,类似垃圾回收机制 --》python解释器,回收所有在本次执行过程用到的空间,这是pyhton底层自带的 ''' import sys class Person: def __init__(self,name): print('---------> init',self) #0x0000026751CB2588 self.name = name def __new__(cls, *args, **kwargs): #向内存要空间 --》 内存地址 print('---------> new') position = object.__new__(cls) # 获取到内存地址 print(position) #<__main__.Person object at 0x0000026751CB2588> return position #地址 # return super(Person, cls).__new__(cls) #把对象当函数调用时执行 def __call__(self, name): print('---------->call') print('得到的参数是:',name) def __del__(self): print('----------del-----------') p = Person('Jack') #程序先执行__new__, 然后执行__init__ print(p) #<__main__.Person object at 0x0000026751CB2588>,不加str方法,打印的时地址 #对象当函数调用,必须要重新__call__函数 p('Jerry') #del的引用 p1 =p p2 = p print(p1.name) print(p2.name) p.name = 'Tom' del p2 print('删除p2后:',p.name) del p1 print('删除p1后:',p.name) #查看p的引用次数 del p #p已经彻底被删除,这时调用__del__,然后再执行下面的代码,如果没有del p,会在打印print(n) 之后再执行__del__ # print(sys.getrefcount(p)) n = 2 print(n)
总结
''' 魔术发方法: 5,__str__ , 触发时机:打印对象名时,自动触发去调用__str__里的内容 单纯打印对象名称,出来的是一个内存地址,这对开发者意义不大 如果想打印对象名时,给开发者更多的信息量 注意:一定要在方法中添加return,return之后的内容,就是打印对象看到的内容 ''' import sys class Person: def __init__(self,name,age): # print('---------> init',self) self.name = name self.age = age def __str__(self): return '姓名:'+ self.name + '年龄:' + str(self.age) p = Person('Jack',20) #程序先执行__new__, 然后执行__init__ print(p) #<__main__.Person object at 0x0000026751CB2588>,不加str方法,打印的时地址,加之后,打印Jack ''' 总结:魔术方法 重点: __init__ 构造方法,创建完空间之后调用的第一个方法 __str__ 打印对象更多信息 了解: __new__ 作用:开辟地址空间,建议不需要去重写 __del__ 作用:没有指针引用时,回收地址空间,建议不需要去重写 __call__ 作用:对象当函数使用,根据需要来决定是否重写 '''
8.3 面向对象编程
#猫类 class Cat: type = 'cat' #初始化特征 def __init__(self,nickname,age,color): self.nickname = nickname self.age = age self.color = color def eat(self,food): print(f'{self.nickname} like to eat {food}') def catch_mouse(self,color,weight): print(f'{self.nickname} caught one mouse which is {color} and {weight}kg ') def cat_sleep(self,hours): if hours < 5: print('Please keep sleeping') else: print('Get up quickly to catch mouse') def cat_show(self): print('Show the details of the Cat') print(self.nickname,self.age,self.color) #创建对象 cat1 = Cat('Jerry',2,'White') #通过对象去调用方法 cat1.catch_mouse('black',2) cat1.cat_sleep(8) cat1.eat('golden fish') cat1.cat_show()
这篇关于Python编程学习-基础笔记06的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-03用FastAPI掌握Python异步IO:轻松实现高并发网络请求处理
- 2025-01-02封装学习:Python面向对象编程基础教程
- 2024-12-28Python编程基础教程
- 2024-12-27Python编程入门指南
- 2024-12-27Python编程基础
- 2024-12-27Python编程基础教程
- 2024-12-27Python编程基础指南
- 2024-12-24Python编程入门指南
- 2024-12-24Python编程基础入门
- 2024-12-24Python编程基础:变量与数据类型