当前位置: 代码迷 >> 综合 >> Python笔记-面向对象
  详细解决方案

Python笔记-面向对象

热度:77   发布时间:2023-09-18 22:07:22.0

1.类的设计满足三要素三特性
类名:驼峰命名法
属性:有什么样的特征
方法:有什么样的行为

面向对象的特性:封装 继承 多态

2.内置函数
以 __方法名__ 格式的方法是python的内置函数

 

3.定义简单的类

class 类名 :def 方法 (self ,参数列表) :pass
定义类的时候self参数必须在第一位

 面向对象1

# 小猫爱吃鱼  小猫爱喝水
class Cat:def eat(self):print('吃鱼')def drink(self):print('喝水')# 创建对象
tom = Cat()
tom.name = '托尼'  # 创建属于自己的属性,断点方式可以看到
tom.drink()
tom.eat()
print(tom)  # 输出内存地址# 创建对象2
tom2 = Cat()
tom2.name = '蒂斯'
tom2.drink()
tom2.eat()

面向对象2 

# 小猫爱吃鱼  小猫爱喝水
class Cat:def eat(self):print('%s吃鱼' % self.name)  # 用.self的方式访问对象的属性和方法def drink(self):print('%s喝水' % self.name)# 创建对象
tom = Cat()
tom.name = '托尼'  # 创建属于自己的属性,断点方式可以看到
tom.drink()
tom.eat()
# print(tom)  #输出内存地址# 创建对象2
tom2 = Cat()
tom2.name = '蒂斯'
tom2.drink()
tom2.eat()

4.初始化方法
_init_(self)

5.内置方法
__del__  : 把对象从内存中删除
__str__  : 返回对象的描述信息,可以自定义返回信息

"""
内置方法 __del__ 在调用最后执行,如果使用del方法删除了对象,则在删除前执行
"""class Test:def __init__(self, name):self.name = namedef eat(self):print('%s爱吃鱼' % self.name)def __del__(self):print('%s拜拜' % self.name)ts = Test('tom')
print(ts.name)
# del ts
print('*' * 20)
"""
内置方法 __str__
注意: 1.必须有返回值 2.可以自定义返回信息 3.输出print(ts.name)可以替代为print(ts)  4. 在__del__前执行
"""class Test:def __init__(self, name):self.name = namedef __del__(self):print('%s拜拜' % self.name)def __str__(self):return '自定义返回值%s' % self.namets = Test('tom')
# print(ts.name)
print(ts)
"""
在初始化方法内部定义属性
"""
class Test:def __init__(self):self.name = 'a'  # 初始化方法ts = Test()
print(ts.name)

 

"""
在初始化方法内部定义属性升级版
"""class Test:def __init__(self, name):self.name = namedef eat(self):print('%s爱吃鱼' % self.name)ts = Test('tom')
print(ts.name)ls_ts = Test('city')
ls_ts.eat()

6.封装
把属性和方法封装在一个class类中

"""
tom体重75.0公斤  name  weight
tom每次跑步体重减少0.5公斤  run
tom每次吃东西体重增加1公斤  eat
"""class Per:def __init__(self, name, weight):self.name = nameself.weight = weightdef __str__(self):return 'my name is : %s,weight is : %.1fkg' % (self.name, self.weight)def run(self):print('%s like run' % self.name)self.weight -= 0.5def eat(self):print('%s like eat' % self.name)self.weight += 1pre = Per('tom', 75)
pre.run()
pre.eat()
print(pre)pre_two = Per('city', 45)
pre_two.run()
pre_two.eat()
print(pre_two)

7.私有属性和私有方法
只能在对象内部被引用
以 __方法名  格式定义的方法或者属性都是私有

注意:
其实真正意义上是没有私有属性和方法的  python在处理私有属性或方法的时候,其实用可以__类名__.方法名或者__类名__.属性的方式来调用

class Test:def __init__(self, name, age):self.name = nameself.age = age# self.__name = name# self.__age = agedef pr(self):# def __pr(self):print('%s的年龄是%d' % (self.name, self.age))# print('%s的年龄是%d' % (self.__name, self.__age))test = Test('tom', 18)
print(test.name)
# test.__pr()
test.pr()

8.单继承

class 类名(父类名)pass

继承的术语: 子类 父类 类继承  或者  派生类 基类  类派生

9.继承的传递性
父类A可以派生B  B可以派生C  意味着C拥有A的属性和方法

class A:def eat(self):print('eat')def drink(self):print('drink')class B(A):  # B继承Adef run(self):print('run')class C(B):  # C继承Bdef fly(self):print('fly')a = A()
a.eat()

10.方法的重写(override重新编写)
在继承父类方法后,父类定义的属性和方法不能满足当前类的需求,则可以在当前类中对属性或方法进行修改

class A:def eat(self):print('eat')def drink(self):print('drink')class B(A):  # B继承Adef run(self):print('run')class C(B):  # C继承Bdef fly(self):print('fly')def eat(self):  # 定义一个和父类一样的方法,就是重写print('eat r')c = C()
c.eat()

11.父类的私有属性和方法
子类不能直接调用父类的私有属性和方法
子类通过调用父类的共有方法来间接访问父类的私有属性

class A:def eat(self):print('eat')def drink(self):print('drink')class B(A):  # B继承Adef run(self):print('run')class C(B):  # C继承Bdef fly(self):print('fly')def eat(self):  # 定义一个和父类一样的方法print('eat r')super().eat()  # 调用父类原有的方法print('eat asdasd')c = C()
c.eat()

12.多继承
class 子类名(父类名1,父类名2)
    pass

注意:避免父类1和父类2的方法名重复

class Ba:def test(self):print('爸爸的基因')class Ma:def test2(self):print('妈妈的基因')class My(Ba,Ma):  # 继承Ba和Madef test3(self):passmy = My()
my.test()
my.test2()
print(My.__mro__)

13.__mro__ 方法搜索顺序
主要判断多继承时方法/属性/的调用优先级
例如: print(类名.__mro__)
(<class '__main__.My'>, <class '__main__.Ba'>, <class '__main__.Ma'>, <class 'object'>)
先在当前类中查找方法,如果找不到返回父类,在找不到在object类中查找,如果还没找到就报错

14.新式类和旧式类
新式:以object为基类的类,推荐使用
旧式:不以object为基类的类

python3中,如果不指定父类,默认继承object类;python2,不指定父类则没有

15.多态

class Dog(object):def __init__(self, name):self.name = namedef play(self):print('%s在快乐的玩耍' % self.name)class XtDog(Dog):def play(self):  # 重写print('%s在天上快乐的玩耍' % self.name)class Preson(object):def __init__(self, name):self.name = namedef pre_play_dog(self, dog):print('%s和%s玩的很开心' % (self.name, dog.name))dog.play()wangcai = Dog('旺财')
# wangcai = XtDog('飞天旺财')
xiaoming = Preson('小明')
xiaoming.pre_play_dog(wangcai)

16.类属性
类名.类属性
对象.类属性(不推荐)

class Test(object):# 定义一个类属性count = 0def __init__(self, name):self.name = name# 初始化方法每调用一次,count加1Test.count += 1test = Test('第一次调用')
test1 = Test('第二次调用')
test2 = Test('第三次调用')
# test2.count = 99  # 避免使用对象.属性的方式,引起混淆
print(test2.count)  # 对象.属性的方式也可以执行
print(Test.count)

17.类方法
@classmethod
def run(cls):
    print('类方法定义')

@staticmethod   # 1没有参数,不需要实例属性也不访问类属性;2不需要创建实例,直接用类名.方法名的方式调用
def static():
    print('静态方法定义')

class Test(object):count = 0  # 定义一个类属性def __init__(self, name):self.name = nameTest.count += 1  # 初始化方法每调用一次,count加1@classmethod  # 定义一个类方法def run(cls):print('数量为%d' % cls.count)@staticmethod  # 定义一个静态方法def static():print('静态方法定义')test = Test('第一次调用')
test1 = Test('第二次调用')
test2 = Test('第三次调用')
Test.run()
Test.static()  # 不需要创建实例,直接类名.方法名调用

练习 

"""
1.设计一个game类
2.属性
定义一个类属性top_score 记录游戏的历史最高分
定义一个实例属性player_name 记录当前游戏的玩家名字
3.方法
静态方法 show_help 显示游戏帮助信息
类方法 show_top_score 显示历史最高分
实例方法  start_game 开始当前玩家的游戏
"""class Game(object):top_score = 0def __init__(self, player_name):self.player_name = player_name@staticmethoddef show_help():print('游戏帮助信息显示')@classmethoddef show_top_score(cls):print('历史最高分为%d' % cls.top_score)def start_game(self):print('%s开始游戏' % self.player_name)#  输出游戏帮助信息
Game.show_help()#  输出历史最高分
Game.show_top_score()#  开始游戏
game = Game('小明')
game.start_game()

18.单列设计模式
__new__ 内置静态方法
1.在内存中为对象创建空间
2.返回对象的引用

class Test(object):def __new__(cls, *args, **kwargs):print('分配空间')#  为对象分配空间instance = super().__new__(cls)#  返回对象的引用return instancedef __init__(self):print('初始化输出')test = Test()
print(test)

 单列模式练习

class Test(object):instance = Noneinit_info = Falsedef __new__(cls, *args, **kwargs):if cls.instance is None:cls.instance = super().__new__(cls)return cls.instancedef __init__(self):   # 多次实例只初始化一次的解决办法if Test.init_info:returnprint('初始化输出')Test.init_info = Truetest1 = Test()
print(test1)test2 = Test()
print(test2)

 

19.异常

try正常代码
except 错误类型1报错执行的代码
except 错误类型2 错误类型3报错执行的代码
except Exception as resultprint(result)
else:没有异常执行的代码
finally:不管任何情况都会执行的代码

异常的传递:代码块出现错误的时候会返回调用的一方,如果调用的一方没有对报错处理,
那么错误会往上传递,直到传递到主程序,如果主程序依然没有处理,那么程序被终止
(所以写代码时候不用在每个程序体中都处理错误,只要在主程序中定义就行了)

try:a = int(input('请输入数字:'))result = 1 / a
except ZeroDivisionError:print('输入的数字不能为0')
except ValueError:print('请输入正确的数字')
except Exception as e:   # 捕获未知异常(用在不能提前预判所有报错的时候)print('其他错误%s' % e)

 

主动抛出异常

"""
判断密码长度,足够8位执行,不足抛出异常
"""def input_password():pwd = input('请输入密码:')if len(pwd) >= 8:return pwdex = Exception('密码长度不够')   # 核心代码raise extry:input_password()
except Exception as result:print(result)

20.模块

格式: import 模块名
格式: import 模块名  as 模块别名   (大驼峰命名法,使用模块别名.方法名)
格式: from 模块名 import *   (从模块导入所有工具,但是不推荐使用)
格式: from 模块名 import 工具名   (只导入部分工具,直接使用工具)
注意: 如果两个模块存在名称相同的方法,那么后导入的方法会覆盖先导入的方法
办法: from 模块名 import 工具名 as 工具别名

21.模块导入的顺序
先从当前目录搜索,找不到则去其他目录搜索
import random
print(random.__file__)  # 查看当前random的文件目录

 

22.测试模块__name__函数

如果被其他文件导入,则__name__的值为模块名
如果执行当前的程序,则__name__的值为__main__
def main():pass
if __name__ == '__main__'main

23.包(包含多个模块的特殊目录)
每个包下都有一个单独的__init__.py文件
要在外界使用包中的模块,需要在__init__.py文件中指定对外提供的模块列表
格式: from . import 模块  (从当前目录导入模块)

import 外界包名
使用:  外界包名.模块名.属性

24.发布/安装/卸载模块
1.创建setup.py
2.构建模块  python3 setup.py build
3.生成发布压缩包  python3 setup.py sdist

from distutils.core import setupsetup(name="Hello",  # 包名version="1.0",  # 版本description="a simple example",  # 描述信息long_description="简单的模块发布例子",  # 完整描述信息author="onefine",  # 作者author_email="188302531@qq.com",  # 作者邮箱url="www.onefine.top",  # 主页py_modules=["hello.request","hello.response"])  # 记录包中包中包含的所有模块

1.tar -zxvf 压缩包名   (解压)
2.sudo python3 setup.py install (安装)
3.导入使用

1.cd 安装目录
2.sudo rm -rf 目录名

25.使用pip安装第三方模块

sudo pip3 install 模块名  (pip和pip3)
sudo pip3 uninstall 模块名