pythonOOP

具体语法

Class 类名:
    变量 =#类属性,公共属性
    def 方法名(self,[参数]):#self代表实例(对象)本身
        方法体
        。。。
    def 方法名(self,[参数]):
        方法体
        。。。

​ 类名其实是一个标识符,建议使用 大驼峰命名法

是用来创建对象的直接运行没有任何效果

​ 如果类里面没有任何代码就要加上 pass

创建对象

变量 = 类名()

​ 由 创建的对象每次都会开辟 新的空间

​ 使用 id() 查看创建后 对象的地址

​ 先有 再有 对象

属性与方法

​ 属性可以在 类里面添加 也可以在创建对象后添加

​ 访问属性:

 对象.属性名
 #如果没有这个属性,就可以直接通过赋值来创建
 对象.属性名 = 属性值
 #此方法也可以修改属性

删除属性

del 对象.属性名

判断属性是否存在

bool = basattr(对象.属性名)#返回布尔

方法

​ 基本语法:

对象.方法名()  #一定假括号
  1. 一个方法可以多次调用
  2. 对象苦于调用使用的可以使用的方法
  3. 如果方法有返回值,就用变量去接收

dir()

  • 查看对象由那些属性和方法
dir(对象)

初始化__init__()

​ 每次开机都会初始化,在python里面的初始化方法__init__

是当你创建对象时,自动调用并执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NGMnYqla-1679640031131)(C:\Users\Yuan\Desktop\python面向对象\文件__init__方法图解.PNG)]

class 类名:
    def __init__(self,[参数]):
        #绑定初始的属性
    	self.属性名1 =1
        self.属性名2 =2
        ...
        
#创建对象
变量 = 类名()
#创建兑现时自动调用并执行

作用:绑定一些初始的属性

__str__()方法

​ 固定名字的方法:__str__(self) 只有一个参数

​ 通过print(对象),打印时自动调用__str__ 方法,该方法返回(return)一个字符串

作用:用于自定义打印出的对象信息

​ 注:如果在类中定义了__str__ 没有返回值的话会报错

class 类名:
	def __str__(self):
		return '自定义对象信息'

对象变量 = 类名()
print(对象变量)

>>> 自定义对象信息

私有成员

​ 在类中以两个下划线开头的成员被称之为私有成员

class 类名:
    def __init__(self):
        #私有属性
        self.__属性名 =def __方法名():
        pass

作用:私有成员不能在 外部使用 ,只能在 的内部使用

  • ​ 可以在类里面访问后输出或者返回

    dir() 输出时也会输出私有成员,但是会被python加上前缀 z类名

  • 一个属性一旦被私有化,在底层形成了 _类名__属性名 的属性名

    可以通过_类名__属性名 直接访问

__del__()方法

​ 当我们的对象被销毁的时候自动调用并执行

​ 对象被销毁:

​ 当代码执行完毕时候对象会被销毁

作用:用于对象被销毁的时候处理一些亲历下工作(比如文件关闭),由于python具有自动垃圾回收机制,所以不动手清理关系也不大

class 类名:
    def __del__(self):
        pass

​ del 类名.属性名/方法名 #可以删除属性或方法

主要查看对象到底在哪里被销毁

  • :只有当所有对象的引用变量删除(del)时对象才被真正销毁,如果引用后的变量再被其他值引用,那也能被销毁
  • 当对象没有被任何变量引用时,对象被销毁

__slots__方法

__slots__ 限定绑定类属性,就是传入这个方法的 参数才能用作于类属性

class 类名:
    __slots__ = (属性1,属性2,...)

实列:

​ 该方法用于控制防止类的外面自定义属性导致报错

class Person(object):
    __slots__ = ('name', 'age')

    def eat(self, food): 
        print(food)


p1 = Person()
p1.name = 'Lucy' #只指定这两个属性,如果有其他属性写入就报错
p1.age = 18
# p1.height = 178  # AttributeError: 'Person' object has no attribute 'height'

@property装饰器

​ 用作于把 类方法 转为 类属性 调用

​ 如:show()使用@property修饰,则 show() 的调用:对象名.show

class Check(object):
    @property
    def show(self):
        # 如果函数被@property修饰,最好设置返回值
        return 'hello'


c = Check()
# c.show()  #TypeError: 'str' object is not callable
print(c.show)  # hello

如果被 @property 装饰,最好设置返回值

为了简化函数的调用,Python中通过 @property 和 @xxx.setter 分别修改两个函数。
注意:

  • 两个函数的函数名尽量和被私有化的属性名保持一致
  • @xxx.setter 中的 xxx 需要和被 @property 修饰的函数名保持一致
  • @property 修饰的函数用于获取值,@xxx.setter 修饰的函数用于修改值
  • @property@xxx.setter 并不是需要同时出现,根据自己的需求进行选择
  • @property出现,@xxx.setter 可以不出现
  • @xxx.setter出现,@property 必须出现

@属性名.setter

​ 也是装饰器的一种,用于修改值

class Decorate (object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name
    '''
        name是被property装饰的name,目的是让name可以作为左值,name.setter后,就可以定义一个修改name的方法了,只能接收一个参数,用来作为等号的右值
    '''

check = Decorate('张飞', 18)
print(check.name)
check.name = 'bob'
print(check.name)

>>> 张飞
>>> bob

@属性名.deleter

​ 使用这个装饰之后,当属性被 del 属性 时这个装饰器中的方法会被调用

class Decorate (object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name
	
    @name.deleter
    def name(self):
        del self.__name # 删除属性
		print('属性已被删除')

check = Decorate('张飞', 18)
print(check.name)

check.name = 'bob'
print(check.name)

del check.name

>>> 张飞
>>> bob
>>> 属性已被删除

继承

​ 继承是发生在有从属关系的两个类上

​ 即 子类继承父类

子类继承父类,子类直接可以使用父类上的属性和方法,不用重复再写,达到代码的复用

class 子类名(父类名):
    #属性
    #方法
  • 如果没有任何父类继承,()可以不用写,要写就写(object) object:是python的初始父类,所有类都是它的子类
  • 子类不能继承私有成员

单继承

​ 一个类继承一个父类,就被成为i单继承

class Father(object):
    pass
class Son(Father):
    pass

在子类的构造函数中调用父类的构造函数

方式一:
    super(当前类, self).__init__(参数列表)

方式二:
    super().__init__(参数列表)

方式三:
    父类名.__init__(self, 参数列表)

注意:在单继承中,三种方式都可以使用;在多继承中,只能使用方式三

**继承中的__slots__ **

__slots__ 定义的属性仅对当前类的实例起作用,对继承的子类实例是不起作用

​ 如果字类本身也有__slots__属性,子类的属性就是自身的 __slots__ 加上父类的 __slots__

多层继承(继承链)

class A(object):
    pass
class B(A):
    pass
class C(B):
    pass

多继承

​ 一个类可以继承多个父类

class 类名(父类1,父类2...):
    pass

重写

​ 发生在 继承关系

​ 指子类中出现父类 相同名字 的属性或方法

重写的意义:当父类上的方法满足不了子类的时候,不能直接更改父类代码,只能在子类中重写

class Father(object):
    def A(self):
        pass
class Son(Father):
   def A(self):
    	print('还是会运行子类')
        pass
  • 子类如何调用父类上的方法
super().父类方法名([实参])

多态

​ 调用相同的方法,实线不同的功能

class Animal(object):
    #动物类
    def run(self):
        print("不知怎么跑")
        
class Dog(Animal):
    #狗类
    def run(self):
        print('四条腿汪汪跑')
        
class Snake(Animal):
    #蛇类
    def run(self):
        print("梭梭的跑")
        
#创建对象
dog = Dog()
snake = Snake()

### 定义一个控制函数
def ganAnimal(animal):
	#驱赶动物
    animal.run()#先写入一个调用方法的代码
    
#调用函数
ganAnimal(dog)#把对象传输进去,在函数里调用类
ganAnimal(snake)

类属性与对象属性

类属性

​ 因为 本身就是一个对象,所以也可以给他添加属性

#添加类属性
	1.类名.属性名 =2.class 类名(object):
        类属性名 =#访问类属性
	类名.类属性名
	类名.类属性名 = 新值
	del 类名.类属性名

对象属性

​ 每个对象都有属性,也被称之为实例属性

对象.属性名 = 值
self.属性名 =

区别

类属性 和 实例属性 的区别

​ 类属性保存在类上面,所以所有的对象都能共享这个数据

​ 非标准访问类属性:

​ 对象. 类属性

使用共享属性可以降低内存的占用

类方法和静态方法

###类方法

class 类名(object):
    
	@classmethod     #装饰器声明类方法
	def 类方法名(cls):   #没有self
		方法体
  • 类方法只能使用类上的属性和方法

    ​ 类名.类属性名

  • cls (class),代表的是类本身

    ​ cls.属性名

    必须先用@classmethod 声明

调用类方法:

类名.类方法名([实际参数])

不用创建对象直接通过类就能调用

静态方法

class 类名(object):
    
    #用于声明静态的方法
    @staticmethod    #声明静态方法
    def 静态方法名():  #无固定参数
        方法体
  • 静态方法:当方法中不使用类上的成员,这个时候就被定义为静态方法

调用方法

类名.静态方法名()

#__new__

​ 创建对象的时候自动调用执行,优先级先于__init__

​ 因为__new__ 用作于在内存中开辟新的空间(底层会调用)

应用:可以稍微改变对象空间的创建过程

class 类名(object):
    def __new__(cls,[形式参数]):
        return super().__new__(cls)
        #子类调用父类的方法用super(),所以将开辟的新对象空间返回,就会成为__init__的self,因为self其实就是类的空间的指针
        #因为object里面有__new__,所以相当于重写
    
    def __init__(self,[形式参数]):
        pass
  • __new____init__形式参数必须一致,因为都要默认调用
  • 对象 = 类名([实际参数])
  • 可以通过 super().__new__(cls) 就能开辟新空间
  • 最后将创建的对象空间返回

单例模式

​ 是23种设计模式的一种

​ 一个类的对象尤其只有一个,一个对象足以满足使用的需求,就没必要创建多个,浪费空间

以**__new__** 来更改创建的内存空间,无论实列化多少个对象,他们的类中的内存地址都相同

# 案例:了解单列模式
class Singleton(object):
    # 类属性
    flag = False
    singleton = None

    def __new__(cls, *args, **kwarge):
        # flag = False #定义一个控制变量,但如果写在这里每次调用都会开辟因为是 "局部变量"
        # 因为我们要多次实例化但是只开辟一个空间,所以我们要拿一个变量来控制,但是不能在里面创建,因为在里面创建是局部变量下一次就每一列
        if cls.flag == False:
            cls.flag = True

            cls.singleton = super().__new__(cls, *args, **kwarge)
            return cls.singleton
        else:
            return cls.singleton


'''
    解析:首先第一个实列化开辟空间,开辟后flag = True,属性singleton也保存了super().__new__
    然后再创建第二个时,因为上一个flag = True,所以执行else,因为是返回singleton然后singleton
    刚好保存的是上一个开辟的空间就达到了单列模式 
'''

son1 = Singleton()
son2 = Singleton()
print(son1, son2)

异常

​ python代码中的错误,如果出现错误代码执行的时候就抛出异常,并且中断代码执行

## 异常处理

​ 先捕获,再处理

try:
    可能出错的代码块
except:
    处理异常(打印,保存到文件,继续抛出)

    ###后面的语句无论有错继续执行

​ python中有一个基础异常类BaseException 所有他的子类都继承他

​ 在代码中能够捕获并让代码继续执行的错误类型都是Exception类或他的子类型

以下是系统异常类型,直接中断代码执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J46eCr35-1679640031133)(C:\Users\Yuan\Desktop\python面向对象\文件\异常的类型.PNG)]

try:
    可能出错的代码块
except 异常类名1:
    处理异常(打印,保存到文件,继续抛出)
except 异常类名2:
    处理异常(打印,保存到文件,继续抛出)
except (异常类名3,异常类名4):
    处理异常(打印,保存到文件,继续抛出)

try: 里面的代码块,只要一行错误,以下代码就不再继续执行

​ 如果制定了错误类型,只会捕获该错误,其他的不会捕获

捕获所有错误

try:
    可能出错代码
except Exception:
    异常处理

获取系统提供的错误信息

try:
    可能出错代码
except Exception as E:
    异常处理
   
E:就是错误对象可以直接输出,获取之后系统就不会再报错

异常的完整语法

try:
    可能出错代码
except 异常类名 as e:
    捕获指定类型的错误
except (异常类名1,异常类名2):
    同时捕获多种类型的异常
except Exception as e:
    捕获所有异常
else:
    没有异常的时候执行这里,告知我们的代码没有错误
finally:
    无论如何都指向小河里

异常传递

如果没有捕获异常,异常就会向外抛出(如在函数里异常就会返回异常),只要最后一层捕获就能处理,如果没有捕获,异常正常抛出中断代码执行

模块和包

模块

​ 一个 .py 文件就是一个模块

如何使用模块

  • import 模块名 一次性导入模块中所有内容
  • from 模块名 import 类/函数/变量 单独导入模块中的某个内容
  • from 模块名 import * 一次性导入模块中的所有内容
  • from 模块名 import 类/函数/变量,类/函数/变量,类/函数/变量… 单独导入模块中的所有内容

使用模块

模块名./函数/变量

注意:

​ from 模块名 import *

​ 该语法是将模块中的所有内容全部导入,期望只导入部分

​ 实现:

​ 在模块最上面通过__all__=['内容1','内容2',...] 来定义那些内容能够被导入

​ 包其实就是一个目录(文件夹)

​ 标准的包下都有文件 __init__.py

​ 是包的初始化文件

包的使用

  • 导入包里面的模块
    • import 包名,模块名
  • 导入包中的指定模块
    • from 包名 import 模块1,模块2
    • from 包名.模块名 import 类/函数/变量
    • from 包名.模块名 import *
模块名.方法()/属性

注意:

​ 包中的__init__.py 才是用来控制包里的模块是否被导入,所以__all__ 关键字是写在**__init__.py** 里面

#__init__中
__all__ = ["模块名1","模块名2",...]

模块加强

​ 模块的位置(存储位置)

​ 1 . 内建模块(built-in)

​ 在 python.exe 解释器里面

​ 查看标准模块

​ 先导入 import sys

​ 然后 print(sys.module)

​ 返回键值对,如果是内建就是 <built-in> ,如果不是内建就是标准的模块

2 . 标准模块

​ 在python安装路径/Lib目录中,是自带的随时都可以使用

3 . 自定义模块

​ 位置:主执行文件所在的当前目录下或者子目录下

4 . 第三方模块

​ 位置:python安装路径/Lib/site-packages

5 . 自定义指定模块路径(用于改变第3条)

​ 用法: import sys

​ sys.path.append(“自定义路径”) #添加到最后

​ sys.path.insert(0,“自定义路径”) #添加到最前面

解决模块错误问题

​ 如果系统模块路径没有这个包,或者自定义的包不再执行文件目录下就会报错

python模块查找顺序

​ 内建 -> 标准 -> 当前目录 -> 第三方 -> 自定义

如果模块重名了

​ 根据导入顺序,如果你在与其他第三方模块重名之前导入那没有问题,但是如果你在导入后报错,那就需要在sys.path.append()添加

​ pycharm是自动添加的

装饰器

在不改变原函数代码的基础上,添加性功能加强

原理
装饰器其实就是一个闭包函数

​ 外函数的形式参数为原函数

​ 内函数调用原函数

it__.py`** 里面

#__init__中
__all__ = ["模块名1","模块名2",...]

模块加强

​ 模块的位置(存储位置)

​ 1 . 内建模块(built-in)

​ 在 python.exe 解释器里面

​ 查看标准模块

​ 先导入 import sys

​ 然后 print(sys.module)

​ 返回键值对,如果是内建就是 <built-in> ,如果不是内建就是标准的模块

2 . 标准模块

​ 在python安装路径/Lib目录中,是自带的随时都可以使用

3 . 自定义模块

​ 位置:主执行文件所在的当前目录下或者子目录下

4 . 第三方模块

​ 位置:python安装路径/Lib/site-packages

5 . 自定义指定模块路径(用于改变第3条)

​ 用法: import sys

​ sys.path.append(“自定义路径”) #添加到最后

​ sys.path.insert(0,“自定义路径”) #添加到最前面

解决模块错误问题

​ 如果系统模块路径没有这个包,或者自定义的包不再执行文件目录下就会报错

python模块查找顺序

​ 内建 -> 标准 -> 当前目录 -> 第三方 -> 自定义

如果模块重名了

​ 根据导入顺序,如果你在与其他第三方模块重名之前导入那没有问题,但是如果你在导入后报错,那就需要在sys.path.append()添加

​ pycharm是自动添加的

装饰器

在不改变原函数代码的基础上,添加性功能加强

原理
装饰器其实就是一个闭包函数

​ 外函数的形式参数为原函数

​ 内函数调用原函数

​ 将内函数作为数据进行返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值