Ⅴ-Python面向对象

目录

        1.面向对象

        2.类的定义

        2.1实例化对象

        2.2类变量

        3.魔法函数

        3.1init()构造函数

        3.2__str__()

        3.3__call__()

        3.4__new__()

        4.三大特性

        4.1封装

        类方法

        静态方法

        4.2继承

        4.3多态

        5.__slots__

        5.1类装饰器

        6.思维导图


1.面向对象

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

Python中万事万物皆对象,而面向对象的三大特性:封装、继承和多态。

常见的面向对象编程语言:Java / C++ / Python等等。

2.类的定义

Python 中定义一个类使用 class 关键字实现,其基本语法格式如下:

class 类名:
    多个(≥0)类属性...
    多个(≥0)类方法...



#Python 类中属性和方法所在的位置是任意的,即它们之间并没有固定的前后次序。

和变量名一样,类名本质上就是一个标识符,因此我们在给类起名字时,必须让其符合 Python 的语法。

有读者可能会问,用 a、b、c 作为类的类名可以吗?

从 Python 语法上讲,是完全没有问题的,但作为一名合格的程序员,我们必须还要考虑程序的可读性。

因此,在给类起名字时,最好使用能代表该类功能的单词。

class Dog:
	name: str = "小黑"
	age: int = 2

2.1实例化对象

2.2类变量

通过类对象来调用所属类中的类变量:(此方式不推荐使用)
# 实例化对象
d1 = Dog()
# 获取对象中的属性
print(f"name={d1.name},age={d1.age}")
# 修改对象中的属性
d1.name="小黑"
d1.gender="公"
print(f"name={d1.name},gender={d1.gender}")

类变量指的是在类中,但在各个类方法外定义的变量。

所有类的实例化对象都同时共享类变量:
class Dog:
    name: str = "小黑"  # 类的属性
    age: int = 2


# 实例化
dog = Dog()
dog2 = Dog()
# 以下访问的是类属性
print(Dog.name)
print(dog.name)
print(dog2.name)
# 向dog实例添加name属性
dog.name = "小花"
print(dog.name)
dog2.name = "小白"
# 向Dog类添加sex类属性
Dog.sex = '公'
print(dog.sex)
#通过类名调用类变量和修改类变量的值:
# 使用类名直接调用
print(f"name={Dog.name},type={Dog.type},age={Dog.age}")
# 修改类变量的值
Dog.name="钱多多"
print(Dog.name)

注意:通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量

3.魔法函数

Python 类中,凡是以双下划线 "" 开头和结尾命名的成员(属性和方法),都被称为类的特殊成员(特殊属性和特殊方法)。例如,类的 init__(self) 构造方法就是典型的特殊方法。
 

3.1init()构造函数

在创建类时,我们可以手动添加一个 __init__() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

Python类中,手动添加构造方法的语法格式如下:

def __init__(self,...):
    代码块
"""
init函数
1.self:名称可以任意,位于方法第一个参数,代表当前对象
2.当实例化类时,init方法会自动调用
3.python中没有重载,参数使用默认值
"""

class Car:
    # 类变量:所有实例共享
    total_count: int = 0

    def __init__(self, brand: str, color: str):
        # 实例变量,动态向当前对象self中添加brand,color实例变量
        self.brand = brand
        self.color = color
        Car.total_count += 1


c1 = Car('比亚迪', '棕色')
c2 = Car('大众', '红色')
print(c1.brand, c1.color)
print(c2.brand, c2.color)
print(Car.total_count)

3.2__str__()

重载父类object中的__str__()用于将值转化为字符串形式:

"""
__str__:默认返回 类的全路径,内存地址:
特点:print时会自动调用
"""
class Dog:
	def __str__(self):
		return f"name={self.name},age={self.age},sex={self.sex}"

3.3__call__()

"""
__call__:类实例对象可以像调用普通函数那样调用call函数
"""
class Dog:
    # 定义__call__方法
    def __call__(self,name,age):
        print("调用__call__()方法",name,age)
d1 = Dog()
d1("小花",2)

3.4__new__()

"""
    1.new和init都会被自动调用
    2.new创建对象,init使用new创建的对象进行初始化属性

    cls:代表当前类,通过它访问类的成员
"""

class AppConfig(object):
    ac = None

    def __new__(cls, *args, **kwargs):
        print("new...")
        if not cls.ac:
            cls.ac = object.__new__(cls, *args, **kwargs)
        return cls.ac

    def __init__(self):
        print('init...')


a1 = AppConfig()
a2 = AppConfig()
print(a1 == a2)

 更多内容,请查看 Python中的魔法函数

4.三大特性

封装、继承、多态。

4.1封装

封装:将属性和实现细节隐藏,提供可访问的接口。

类方法

Python 类方法和实例方法相似,它最少也要包含一个参数,和实例方法最大的不同在于,类方法需要使用@classmethod修饰符进行修饰,例如:

 # 类方法 cls代表当前类,通过cls调用类的成员
class Dog:
	# 类方法
    @classmethod
    def info(cls):
        print(cls)

静态方法

静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。

静态方法需要使用@staticmethod修饰,例如:

 # 静态方法 类的静态方法中无法调用类任何属性的类方法
    @staticmethod
    def say():
        print("静态方法被调用了...")

4.2继承

Python 中,实现继承的类称为子类,被继承的类称为父类(也可称为基类、超类)

子类继承父类时,只需在定义子类时,将父类(可以是多个)放在子类之后的圆括号里即可。语法格式如下:

class 类名(父类1, 父类2, ...):
    #类定义部分
class Father(object):
    height = 180
    money = 100

    def work(self):
        print("会工作")

    pass


class Mother(object):
    fact = '漂亮'
    money = 90

    def cook(self):
        print("会做法")

    pass


class Son(Father, Mother):
    pass


son = Son()
son.work()
son.cook()
print(son.height)
print(son.money)
#同时继承 Father类和 Mother类时,Father类在前,当属性和方法重复时,越往前优先级越高。


#查看继承关系
print(Son.__bases__)
print(Son.__mro__)  # mor 决定查找方法的路径

4.3多态

# 多态
class Animal(object):
    def play(self):
        pass


class Tiger(Animal):
    def play(self):
        print("正在表演老虎后脚直立行走")


class Lion(Animal):
    def play(self):
        print("正在表演狮子跳火圈")


class Person(object):
    def show(self, a: Animal):  # 声明父类类型,传入子类实例
        print("动物表演开始了")
        a.play()  # 多态


p = Person()
a = Animal()
t = Tiger()
l = Lion()

p.show(t)

5.__slots__

每个类都有实例属性。默认情况下Python⽤⼀个字典来保存⼀个对象的实例属性。所以我们在可以在运⾏时去设置任意的新属性

Python 提供了 __slots__ 属性,通过它可以避免用户频繁的给实例对象动态地添加属性或方法。

# __slots__
class Dog(object):
    __slots__ = ["name","age"]

    def __init__(self,name,age):
        print("实例化")
        self.name = name
        self.age = age

dog = Dog('小猴','12')

5.1类装饰器

类装饰器在内部的装饰函数是用__call__() 方法实现的。

class Logger(object):
    def __init__(self, path='out.txt'):
        self.path = path
    def __call__(self, func):
        def inner():
            log = func.__name__ + "执行"
            with open(self.path, 'a') as opened_file:
                opened_file.write(log + '\n')
            self.notify()
        return inner
    def notify(self):
        pass

@Logger()
def hello():
    pass

hello()


#@Logger 在这里的作用实际就是实例化一个fun对象(fun=Logger(fun))

6.思维导图

----------------------------------------------------------------------------------------♥-------------------------------------------------------------------------------------

往期Python内容:

Ⅰ-Python入门与基本语法

Ⅱ-Python运算符(进阶语法)

Ⅲ-Python函数的使用

Ⅳ-Python函数进阶

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值