0
点赞
收藏
分享

微信扫一扫

python学习--面向对象(初级)

小_北_爸 2022-03-10 阅读 57

面向对象(初级)

生活中有很多类,人类、鸟类、动物类等等。这些类都有他们共有的属性和能力。那么我们就可以用类来定义一个人类,其中人类的一个实例化变量称为对象。

1.类的作用

类似于函数将一段代码组合至一起,类可以将变量和函数组合至一起。

2.类的定义

类定义首字母需大写

class Person:  # 定义一个人类,类中的内容都要在缩进中。
	name = "ice"
	
    def eat(self):
        print("I am eating")

这里的self将在后面提起。

3.类的变量

可以直接用类.变量来获取对类的变量,但是直接使用变量则会报错。即使在这个类中的函数里也不能直接使用变量。

print(Person.name)  # ice
print(name)  # 报错

4.类的方法

与变量一样

Person.eat(Person)  # I am eating

5.类的实例化

类似于list.sort()其实list就是对象,而sort是list对象的一个方法。对象其实就是类的一个实例化对象,和变量定义一样:

ps = Person()  # 实例化一个人

5.类的初始化

就是常见的def __init__(self):这个就是类的初始化函数。会在类实例化的过程当中自动调用。类似__init__带有下划线的是python中已经拥有的方法,具有特殊能力,称之为魔术方法,不可改名称

class Person:
    name = "ice"

    def eat(self):
        print(f"{self.name} is eating")

    # def __init__(self):
    #     print("我正在实例化")

    def __init__(self, name):
        self.name = name


# ps = Person()  # 我正在实例化
ps1 = Person("ice")  # 实例化一个ice对象
ps2 = Person("冰鸽")  # 实例化一个冰鸽对象
ps1.eat()  # ice is eating
ps2.eat()  # 冰鸽 is eating

由此我们可以定义两个不同的对象。值得注意的是,当一个类没有定义def __init__(self):时,该类会自动生成一个空的初始化函数,但一旦定义之后,这个空的初始化函数将不存在。并且一个类只能定义一个初始化函数。

6.类中的self

在我们进行实例化对象时,这个self就代表着该对象,在类函数中必须含有第一个参数,而这个参数一般是self。可以理解为该变量作为参数传入函数中。由于在类的函数中不好用某个实例化对象.变量,则可以改成self.变量

面向对象与面向过程

举个例子:吃面条

  • 面向过程:买面条->洗锅->烧水->煮面条->吃面
  • 面向对象:进食堂->点面->吃面

也就是面向对象将买面条->洗锅->烧水->煮面条这一系列操作封装至进食堂->点面中。

析构函数

析构函数定义为def __del__(self):在删除实例化对象时自动调用。我们使用del进行对象的删除。

    def __init__(self, name):
        self.name = name

    def __del__(self):
        print(f"{self.name} 被删除了")


ps1 = Person("ice")
del ps1  # ice 被删除了

类的继承和重用

一个类可以继承其他类,从而获得他们的能力。

1.继承

对于人类,有些人主要吃米饭,而有些人主要吃面条,这样就可以分出两个类,但是这两个类相似点太多,如果重新定义的话会导致代码大量重复。于是就出现了继承。

class Person:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("吃白米饭")

    def sleep(self):
        print("睡觉")


class Sichuan(Person):  # 四川人的类继承人类
    def eat(self):
        print("四川人喜欢吃火锅")


ps1 = Person("ice", 19, "man")
# ps2 = Sichuan()  # 当类继承且本身没有初始化函数时他也要像父类那样实例化
ps2 = Sichuan("冰鸽", 19, "man")

ps1.sleep()  # 睡觉
ps1.eat()  # 吃白米饭
ps2.sleep()  # 睡觉

由代码可以看出ps2对象继承了父类的sleep函数。
补充一下所有的类都继承object类。

2.重用

可以发现Person类与Sichuan类共同具有eat函数,当对象ps2调用eat函数的时候到底时执行哪个呢,显然是执行子类的函数,这个叫做方法的重用。

ps2.eat()  # 四川人喜欢吃火锅

3.子类访问父类

子类可以通过super().的形式访问父类的方法或变量。

class Sichuan(Person, object):  # 四川人的类继承人类
    def eat(self):
        print("四川人喜欢吃火锅")
        super().eat()

这样就可以实现既吃火锅又吃米饭了。

多继承

假设现在有一个四川人和一个广东人结婚生下了一个混血儿,此时混血儿就继承两个类了。

class Sichuan(Person, object):  # 四川人的类继承人类
    def eat(self):
        print("四川人喜欢吃火锅")
        super().sleep()


class Guangdong:
    def eat(self):
        print("广东人喜欢喝茶")


class Hunxue(Sichuan, Guangdong):
    def eat(self):
        print("混血儿喜欢吃汉堡")
        super().eat()


hx = Hunxue("混血", 18, "woman")
hx.eat()  # 四川人喜欢吃火锅

可以看到多继承时是具有优先级的,在左边的优先级最高,所以上述eat方法输出结果为四川人喜欢吃火锅。

1.查看继承顺序

利用Hunxue.mro可以得到混血的继承顺序。

  1. <class '__main__.Hunxue'>
  2. <class '__main__.Sichuan'>
  3. <class '__main__.Guangdong'>
  4. <class '__main__.Person'>
  5. <class 'object'>

由此可以看出Sichuan类优先级最高,与此同时可以发现Sichuan继承Guangdong,但当我们单独对这两个类使用mro时他们之间没有直接关系。

即使是这样,如果我们在以上代码的基础上在Sichuan的eat中加入super().eat()那么他的输出则应该按照出发点(也就是Hunxue)的继承顺序执行。所以他的输出是广东人喜欢喝茶

上次练习答案

import datetime


# 利用datetime模块,批量生成月份每天的txt文件
import os


def fun1():
    for i in range(1, 31):
        dt = datetime.datetime(2022, 1, i)
        s = dt.strftime("%Y-%m-%d")
        # print(s)
        file = open("../file/" + s + ".txt", "w")


# 生成上面的文件之后,再一次在每个文件中写入文件名
def fun2():
    for i in range(1, 31):
        dt = datetime.datetime(2022, 1, i)
        s = dt.strftime("%Y-%m-%d")
        filename = s + ".txt"
        str = "../file/" + filename
        file = open(str, "w")
        file.write(filename)
        file.close()


# 将上面生成的所有文件名之后加上‘_NEW’
def fun3():
    for i in range(1, 31):
        dt = datetime.datetime(2022, 1, i)
        s = dt.strftime("%Y-%m-%d")
        filename = s + ".txt"
        filename_new = "../file/" + filename
        os.rename(filename_new, filename_new + "_NEW")


# 假设有一个英文文本文件,编写一个程序读取其内容,并将里面的大写字母变成小写字母,小写字母变成大写字母
def fun4():
    file = open("../file/a.txt", "a+")
    file.seek(0)
    str1 = file.readlines()
    file.close()
    file = open("../file/a.txt", "w")
    for i in str1:
        j = i.swapcase()
        file.write(j)
    file.close()


# fun1()
# fun2()
# fun3()
# fun4()

练习

  • 定义一个账户类,可以创建账户、存款、取款 、查询余额、以及销户等操作。
  • 现在三个人分别去开户,存款 和 销户,请利用上面的类实现出来。

结束语

点赞!!!
ps:现在关注我,以后就是老粉啦!!!

下篇预告

之前掌握了类的定义和基本使用,可以通过点操作符去访问属性和方法,但是如果属性不存在会怎么办呢?不希望因为属性不存在而出现报错,如何避免这个问题呢?

举报

相关推荐

0 条评论