Python进阶知识学习

面向对象

面向对象与面向过程的区别:
面向过程:通过一个个方法的执行解决问题,着重的是过程。
面向对象:着重的是谁去帮我做这件事情。

面向对象的三大特征 :封装、继承 、多态。

类与对象

一、类

类:对一系列具有相同属性和行为的事物的统称,不是真实存在的事物。
类的三要素:类名、属性、方法
基本格式:

class  类名:
       代码块

查看类属性:类名.属性名
新建类属性:类名.属性名 = 值

1.新式类写法:

经典类:不由任何内置类派生出的类,例:class A:或class A():
新式类:class A(object) 继承object类或者该类的子类都是新式类。
Python3中如果一个类没有继承任何类,则默认继承object类,因此Python3都是新式类。

二、对象

对象:是类的具体实现,是类创建出来的真实存在的事物,面向对象思想的核心。
创建对象(也称实例化对象)的基本格式:

对象名 = 类名()

例:

class Washer:
    height = 800    #类属性
    def wash(self):     #类方法
        print("我会洗衣服")
        print("方法中的self:",self)     #self表示当前调用该方法的对象
wa = Washer()     #创建对象
print("wa",wa)
wa.wash()    #对象调用类中的方法

在这里插入图片描述

实例属性与实例方法

一、实例属性

1.类属性属于类,是公共的,大家都可以访问到,实例属性属于对象的,是私有的。
2.实例属性只能由对象名访问,不能由类名访问。
3.访问类属性,类可以访问到,实例对象也可以访问到。

二 、实例方法

由对象调用,至少有一个self参数,执行实例方法的时候,自动将调用该方法的对象赋值给self。
例:

class Person:
    sex = "男"     #类属性
    def introduce(self):
        print("我是实例方法 ")
        print(f"{self.name}的年龄是:{self.age},性别是:{Person.sex}")
xiaoming = Person()
xiaoming.name = "xiaoming"    #新增实例属性
xiaoming.age = 18
print(xiaoming.name)     #根据对象名访问实例属性
xiaoming.introduce()

在这里插入图片描述

三、init():构造函数

作用:通常用来做属性初始化或者赋值操作。
在类实例化对象的时候,会被自动调用
例:

class Person:
    def __init__(self,name,age,height):
        self.name = name    #实例属性
        self.age = age
        self.height = height
    def introduce(self):
        print(f"{self.name}的年龄是:{self.age},身高是:{self.height}")
xiaoming = Person("xiaoming",18,183)
xiaoming.introduce()

在这里插入图片描述

封装

封装:将复杂的信息、流程给包起来,内部处理,让使用者只需要通过简单的操作步骤,就能实现,指的是隐藏对象中一些不希望被外部所访问到的属性或方法。
1.xxx:普通属性与方法,如果是类中定义的,则类可以在任何地方使用
2._xxx:私有属性与方法,如果定义在类中,外部可以使用,子类也可以继承,但无法通过from xxx import *导入。
3.__xxx:隐藏属性与方法,如果定义在类中,无法在外部被直接访问,之类不会继承,也无法通过from xxx import *导入。

一、隐藏属性与方法

隐藏属性(私有权限),只允许在类的内部使用,无法通过对象访问。
写法是在属性名或者方法名前面加上两个下划线_
1.隐藏属性实际上是将名字修改为:_类名__属性名(了解)
2.隐藏属性在类的内部访问。(推荐使用,正规手段)
例:

class Person:
    name = "xiaoming"    #类属性
    __age = 28           #隐藏属性
    def introduce(self):
        print(f"{Person.name}的年龄是:{Person.__age}")
xiaoming = Person()
print(xiaoming.name)
# xiaoming._Person__age = 18
print(xiaoming._Person__age)
xiaoming.introduce()

在这里插入图片描述
隐藏方法:在实例方法中调用隐藏方法。
例:

class Man:
    def __play(self):    #隐藏方法
        print("玩手机")
    def funa(self):
        print("平平无奇的实例方法")
        Man.__play(self)    #在实例方法中调用隐藏方法,不推荐
        self.__play()       #推荐使用,更简便
ma = Man()
ma.funa()

在这里插入图片描述

二、私有属性与方法

私有属性:使用对象名._属性名调用
私有方法:使用对象名.方法名调用
例:

class Girl:
    def _buy(self):    #私有方法
        print("整天买买买")
girl = Girl()
girl._buy()

在这里插入图片描述

继承

继承就是让类与类之间转变为父子关系,子类默认继承父类的属性和方法。
语法:

class 类名(父类名)
        代码块

一、单继承

子类可以继承父类的属性和方法,就算子类自己没有,也可以使用父类的。
例:

class Person:     #父类
    def eat(self):
        print("我会吃饭")
    def sing(self):
        print("我是唱歌小能手")
class Girl(Person):    #Person类的子类
    pass    #占位符,代码里面类下面不写任何东西,会自动跳过,不会报错
class Boy(Person):    #Person类的子类
    pass
girl = Girl()
girl.eat()
girl.sing()
boy = Boy()

在这里插入图片描述

1.继承的传递(多重继承)

C(子类)继承B(父类),B(子类)继承A(父类),C类具有A/B类的属性和方法。
子类拥有父类的父类的属性和方法。
继承的传递性就是子类拥有父类以及父类的父类中的属性和方法。
例:

class Father:
    def eat(self):
        print("吃饭")
    def sleep(self):
        print("睡觉")
class Son(Father):    #Father类的子类
    pass
class Grandson(Son):
    pass
grandson = Grandson()
grandson.sleep()
grandson.eat()

在这里插入图片描述

2.方法的重写

方法的重写:指在子类中定义与父类相同名称的方法
1.覆盖父类方法
2.对父类方法进行扩展:继承父类的方法,子类也可以增加自己的功能。
(1)父类名.方法名(self)
(2)super().方法名() ——推荐使用
(3)super(子类名,self).方法名()
super在Python里面是一个特殊的类,super()是使用super类创建出来的对象,可以调用父类中的方法。
例:

class Person:    #父类
    def money(self):
        print("一百万需要被继承")
class Man(Person):    #子类
    def money(self):
        Person.money(self)
        super().money()
        super(Man,self).money()
        print("自己赚一千万")
man = Man()
man.money()

在这里插入图片描述

二、多继承

多继承:子类可以拥有多个父类,并且具有所有父类的属性和方法。
不同的父类存在同名的方法时,调用就近原则,括号里哪个在前,优先调用哪个类的方法。
Python中内置的属性__mro__可以查看方法搜索顺序。
弊端:容易引发冲突,会导致代码设计的复杂度增加。
例 :

class Father(object):    #父类一
    def money(self):
        print("拥有一百万财产需要继承")
class Mother(object):    #父类二
    def money(self):
        print("拥有一百二十万财产需要继承")
    def appearance(self):
        print("绝世容颜需要被继承")
class Son(Father,Mother):
    pass
son = Son()
son.money()
son.appearance()
print(Son.__mro__)

在这里插入图片描述

1.多态:

多态:同一种行为具有不同的表现形式
多态的前提:1.继承 2.重写
例:

class Animal(object):
    def shout(self):
        print("动物会叫")
class Cat(Animal):
    def shout(self):
        print("小猫喵喵喵")
class Dog(Animal):
    def shout(self):
        print("小狗汪汪汪")
cat = Cat()
cat.shout()
dog = Dog()
dog.shout()

在这里插入图片描述
多态性:一种调用方式,不同的执行结果,定义一个统一的接口,一个接口多种实现。
例:

class Animal(object):
    def eat(self):
        print("我会干饭")
class Pig(Animal):
    def eat(self):
        print("猪吃饲料")
class Dog(Animal):
    def eat(self):
        print("狗吃狗粮")
def test(a):    #test函数传入不同的对象,执行不同的对象的eat方法
    a.eat()
animal = Animal()
pig = Pig()
dog = Dog()
test(animal)
test(pig)
test(dog)

在这里插入图片描述

2.静态方法@staticmethod:

使用@staticmethod来进行修饰,静态方法没有self,cls参数的限制。
静态方法与类无关,可以被转换成函数使用。
定义格式:

class 类名:
    @staticmethod
    def 方法名(形参):
        方法体

调用格式:
类名.方法名(实参)
对象名.方法名(实参)

取消不必要的参数传递,有利于减少不必要的内存占用空间和性能消耗。
例:

class Person(object):
    @staticmethod    #静态方法
    def study(name):
        print(f"{name}会学习")
Person.study("xiaoming")    #静态方法既可以使用对象访问,也可以使用类访问
pe = Person()
pe.study("xiaoming")    #调用方法时传参数

在这里插入图片描述

3.类方法@classmethod:

使用@classmethod来标识为类方法,对于类方法,第一个参数必须是类对象,一般是以cls作为第一参数。
定义格式:

class 类名:
    @classmethod
    def 方法名(cls,形参):
        方法体

类方法内部可以访问类属性,或者调用其他的类方法。
应用场景:当方法中需要使用到类对象(如访问私有类属性等),定义类方法时,类方法一般配合类属性使用。
例:

class Person(object):
    name = "xiaoming"
    @classmethod
    def sleep(cls):
        print("cls:",cls)    #cls代表类对象本身,类本质上就是一个对象
        print("人类在睡觉")
        print(cls.name)
print(Person)
Person.sleep()

在这里插入图片描述
总结:
1.实例方法:方法内部访问实例属性,方法内部可以通过类名.类属性名来访问类属性名。
2.静态方法@staticmethod:方法内部不需要访问实例属性和类属性,可以通过类名.类属性名访问类属性,不能访问实例属性。
3.类方法@classmethod:方法内部只需要访问类属性,可通过cls.类属性访问类属性,不能访问实例属性。
4.类属性是公共的,所有方法内部都能够访问到,静态方法不需要访问类属性,因为静态方法和类,对象没有关联。
5.实例属性是私有的,只有实例属性内部能够访问到。

例:

class Person(object):
    name = "xiaoming"    #类属性:类所拥有的属性
    def __init__(self):
        self.age = 18    #实例属性:对象私有的
    def play(self):    #实例方法
        print(f"{self.name}在玩游戏")    #在实例方法中访问类属性
        print(self.age)    #在实例方法中访问实例属性
    @staticmethod    #静态方法,类中的函数,形参没有限制
    def introduce1():
        print(f"我是{Person.name}")    #静态方法能够访问到类属性,但是无意义
    @classmethod    #类方法:针对类存在的方法
    def introduce2(cls):    #cls代表类对象本事
        print(cls.name)
pe = Person()
pe.play()
pe.introduce1()
pe.introduce2()

在这里插入图片描述

单例模式

可以理解成一个特殊的类 ,这个类只存在一个对象。
优点:可以节省内存空间,减少了不必要的资源浪费。
弊端:多线程访问的时候容易引发线程安全问题。
方式:
1.通过@classmethod
2.通过装饰器实现
3.通过重写__new__()实现(重点)
4.通过导入模块实现,模块就是天然的单例模式。

一、new():

new(): object基类提供的内置的静态方法
作用:1.在内存中为对象分配空间。 2.返回对象的引用。
执行步骤:
一个对象的实例化过程:首先执行__new__(),如果没有__new__(),则默认调用object里面的__new__(),返回一个实例对象,然后再去调用__init__(),对对象进行初始化。

例:

class Test(object):
    def __init__(self):
        print("这是__init__()")
        print(self)
    def __new__(cls, *args, **kwargs):    #cls代表类本身
        print("我是__new__()")
        print(cls)
        # 对父类方法进行扩展:super.方法名()
        res = super().__new__(cls)    #方法重写,res里面保存的是实例对象的引用
        # __new__()是静态方法,形参里面有cls,实参就必须传cls
        return res
        #注意:重写__new__()一定要return super().__new__(cls)
        #     否则python解释器得不到分配空间的对象引用,就不会调用__init__()方法
te = Test()
print("te:",te)

在这里插入图片描述
总结:
1.new()是创建对象,init()是初始化对象。
2.new()是返回对象引用,init()定义实例属性。
3.new()是类级别方法,init()是实例级别的方法。

二、通过重写__new__()实现单例模式

设计流程:
1.定义一个类属性,初始值为None,用来记录单例对象的引用。
2.重写__new__()方法。
3.进行判断,如果类属性是None,把__new__()返回的对象引用保存进去。
4.返回类属性中记录的对象引用。
单例模式:每一次实例化所创建的对象都是同一个,内存地址都一样。
例:

class Singleton(object):
    a = None    #类属性,用来记录第一个被创建的对象的引用
    def __new__(cls, *args, **kwargs):
        print("这是__new__()方法")
        if cls.a == None:
            cls.a = super().__new__(cls)
        return cls.a
    def __init__(self):
        print("我是__init__()")
s1 = Singleton()
print("s1:",s1,end="\n\n")
s2 = Singleton()
print("s2:",s2,end="\n\n")

在这里插入图片描述

三、应用场景

1.回收站对象
2.音乐播放器,一个音乐播放软件负责音乐播放的对象只有一个。
3.开发游戏软件,场景管理器。
4.数据库配置、数据库连接池的设计。

魔法方式和魔法属性

1.doc:

类函数的描述信息
例:

class Person(object):
    """人类---类的描述信息"""    #只能使用多行注释,单行注释无效
    pass
print(Person.__doc__)

在这里插入图片描述

2.module:

表示当前操作对象所在的模块

3.class:

表示当前操作对象所在的类
例:

class B:
    def funa(self):
        print("哈哈哈")
b = B()
print(b)
print(b.__class__)

在这里插入图片描述

4.str:

对象的描述信息
如果类中定义了此方法,那么在打印对象时,默认输出该方法的返回值,也就是打印方法中的return的数据。
注意:str()必须返回一个字符串。
例;

class C:
    def __str__(self):
        return "这是str的返回值"    #必须有返回值,并且一定是字符串类型
c = C()
print(c)

在这里插入图片描述

5.del:析构函数

del()主要是表示该程序模块或者函数已经全部执行结束。
1.删除对象的时候,解释器会调用__del__()方法
2.正常运行时,不会调用__del__(),对象执行结束之后,系统会自动调用__del__()
3.del 对象名语句执行的时候,内存会立即被收回,会调用对象本身的__del__()方法

例:

class Person:
    def __init__(self):    #最先执行
        print("我是__init__()")
    def __del__(self):    #最后执行
        print("被销毁了")
p = Person()
print("这是最后一行代码")
del p    #删除p这个对象

在这里插入图片描述

6.call:

使一个实例对象成为一个可调用对象,就像函数那样可以调用。
可调用对象:函数\内置函数和类都是可调用函数,凡是可以把一对()应用到某个对象身上都可以称之为可调用对象。
例:

class A:
    def __call__(self, *args, **kwargs):
        print("这是__cal__()")
a = A()
a()    #调用一个可调用的实例对象,其实就是在调用它的__call__()方法
print(callable(a))

在这里插入图片描述
callable():判断一个对象是否可调用
例:

def func():
    print("哈哈哈")
func()
print(callable(func))
name = "bingbing"
print(callable(name))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值