Day 28 类的定义和方法

@浙大疏锦行
今日任务:

  1. 类的定义
  2. pass占位语句
  3. 类的初始化方法
  4. 类的普通方法
  5. 类的继承:属性的继承、方法的继承

类的定义

对类进行定义时,使用class关键字,注意与函数不同,在类名的后面不需要加括号,示例如下:

python 复制代码
class ClassName: #类名通常遵循大驼峰命名法 (UpperCamelCase),即每个单词的首字母都大写
    """类的文档字符串"""
    # 类的内容
    pass #pass 为占位符,避免运行错误

关于pass与缩进:

  • Python通过缩进定义代码块的结构,对于def,class,if等,如果后续代码块为空,那么就会因为无法确定结构的范围而抛出IndentationError。
  • pass 本身不执行任何操作,但它可以起到一个占位置的作用。因此,当需要一个语法上存在的代码块,但又暂时不想在其中放入任何实际的逻辑时,就可以使用pass占位。

在定义一个类时,它可以具有属性和方法两个部分。

  • 属性(是什么):用于存储数据,初始化方法构造类内部直接定义、类外部添加
  • 方法(做什么):定义行为,初始化方法(init)、类方法、静态方法、魔术方法等等

类的方法

上面提到了类的方法和属性,在调用时,对方法和属性分别使用example.method()、example.name

下面主要说明初始化方法和自定义的普通方法。

初始化方法

init (注意前后均各有两条下划线)属于类的构造方法,当创建对象时,会被自动调用

关于参数,可以自己使用self.属性名给出默认值 或者赋值给外部传入的参数值。

python 复制代码
class Teacher:
    def __init__(self, name, age):# 初始化方法,传入了参数
        print(f"self的内存地址: {id(self)}") #打印内存地址
        self.name = name # 外界的参数,需要通过self.xxx来复制给类自己的属性
        self.age = age
        self.subject = "English"  # 这个属性仍然是在创建时就设定好的

# 创建一个Teacher对象的例子,构造方法的参数必须
teacher_1 = Teacher("Susan", 33) # 如果在初始化方法中设置了非默认的参数,那么外界就必须要传入才行
print(f"teacher_1的内存地址: {id(teacher_1)}")
print(teacher.name)  # 输出: Susan
print(teacher.age)   # 输出: 33
print(teacher.subject)  # 输出: English
teacher_1.subject = 'Math' #修改属性
print(teacher.subject)  # 输出: Math

在使用__init__初始化时,必须先填入'self ',因为self代表的是实例本身(打印内存地址查看):

  • 对同一个类,可以创建不同的实例,每次调用,可以将不同实例作为self参数传入
  • 通过self.属性名 和**self.方法名()**获取实例的属性和方法
  • 数据隔离:确保每个实例有独立的数据空间

注意在对类实例化时,传入的参数是初始化方法中的(一些属性)。后续在普通方法中的参数,是在调用函数的时候传入(与之前的普通函数调用相同)。当然,这些参数肯定是除'self'之外的。

普通方法(自定义)

与Init方法不同,自定义的方法只有手动调用时才会被执行。但相同的时,第一个参数也是'self',原因同上。其他的写法与之前单独的函数写法基本相同,但区别如下:

  • 第一个参数是"self",后面是正常的参数
  • 需要在函数内部使用类的属性和方法 时,必须使用self,比如self.name而不是name
python 复制代码
class Teacher:
    # 初始化方法接受参数以动态设置教师的属性
    def __init__(self, name, subject, age):
        self.name = name
        self.subject = subject
        self.age = age
    # 不是init的都叫做普通方法
    # 普通方法,模拟教师上课的行为
    def teach_lesson(self):
        print(f"{self.name}正在教{self.subject}。")
    # 另一个普通方法,模拟教师批评学生的行为
    def criticize(self, student_name):
        print(f"{self.name}正在批评{student_name}。")

# 创建Teacher类的实例
teacher = Teacher("Susan", "English", 33)
# 调用教师的方法
teacher.teach_lesson()
teacher.criticize("John")#普通方法的参可以等到调用该方法的时候再传

关于构造方法与普通方法的对比:

类的继承

类的继承是面向对象编程的重要特性,允许基于已有的类创建新类 ,而新类会自动获得父类的属性和方法,并可以添加新的功能或修改现有功能。

使用类的继承,实际上很大程度上与之前的函数封装 、装饰器类似,就是减少代码重复。比如定义了一个猫类别和狗类别,然后发现它们中存在相同的地方(吃东西、睡觉),完全可以将这些提取出来,使用一个父类(动物)来包含。猫类和狗类只要继承就可以,而对应于别的动物(鱼类、鸟类)也可以适用。

此外,适用类的继承有如下用途:

  • 建立层次关系,更精确地建模现实世界,比如上面的动物------猫/狗/鱼/鸟
  • 扩展和定制功能,在每一个子类中可以重写新增属性或方法作为自身的特色
  • 多态性、便于维护和更新(修改父类可影响所有子类)

在用代码实现时需要注意:

  • 类名后的括号中填入父类名称(可以不只一个)
  • 使用super() 调用父类方法:子类初始化 或者需要扩展父类方法时使用;完全重写或新增方法时不需要

下面是代码示例:

python 复制代码
# 定义一个父类
class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def sleep(self):
        print(f'{self.name}在睡觉')
    def speak(self):
        print(f"{self.name} 发出声音")
    
class Dog(Animal): #继承需要在括号中指定父类
    def __init__(self,name,age,color): #传入父类的参数,同时也可以传入自己的参数
        # super()函数 除了在构造方法中使用,还可以在其他方法中使用
        super().__init__(name,age) #调用父类的构造方法,super()是一个内置函数,返回父类的实例
        self.color = color #新增子类特有的属性
    #重写方法,如果子类定义了与父类同名的方法,子类实例会优先调用子类的方法。
    def sleep(self): 
        print(f'{self.color}的{self.name}在睡觉')
    #重写------扩展父类功能
    def speak(self):
        super().speak()  # 先调用父类的方法
        print("汪汪叫")    # 再添加子类的行为
    #新增功能
    def run(self):
        pass

dog = Dog("旺财", 3,'红色')
dog.sleep() 

作业

题目1:定义圆(Circle)类

要求:

  1. 包含属性:半径 radius。
  2. 包含方法:calculate_area():计算圆的面积(公式:πr²)。calculate_circumference():计算圆的周长(公式:2πr)。
  3. 初始化时需传入半径,默认值为 1。
python 复制代码
import math
class Circle:
    def __init__(self,radius):
        self.radius = radius
    def calculate_area(self): #计算面积
        area = round(math.pi*pow(self.radius,2),2)
        return area
    def calculate_circumference(self): #计算周长
        circumference = round(2*math.pi*self.radius,2)
        return circumference
#调用
circle = Circle(5)
print(f"半径:{circle.radius}")       # 输出:半径:5
print(f"面积:{circle.calculate_area()}")   # 输出:面积:78.54
print(f"周长:{circle.calculate_circumference()}") # 输出:周长:31.42

题目2:定义长方形(Rectangle)类

  1. 包含属性:长 length、宽 width。
  2. 包含方法:calculate_area():计算面积(公式:长×宽)。calculate_perimeter():计算周长(公式:2×(长+宽))。 is_square() 方法,判断是否为正方形(长 == 宽)。
  3. 初始化时需传入长和宽,默认值均为 1。
python 复制代码
class Rectangle:
    def __init__(self,length=1,width=1): #长和宽默认为1
        self.length = length
        self.width = width
    def calculate_area(self): #计算面积
        area = self.length * self.width
        return area
    def calculate_perimeter(self): #计算周长
        perimeter = 2*(self.length + self.width)
        return perimeter
    def is_square(self): #判断是否为正方形
        return self.length == self.width
    
rect = Rectangle(4, 6)
print(f"长:{rect.length}, 宽:{rect.width}")  # 输出:长:4, 宽:6
print(f"面积:{rect.calculate_area()}")      # 输出:面积:24
print(f"周长:{rect.calculate_perimeter()}")  # 输出:周长:20
print(f"是否为正方形:{rect.is_square()}")    # 输出:是否为正方形:False

square = Rectangle(5, 5)
print(f"是否为正方形:{square.is_square()}")  # 输出:是否为正方形:True

题目3:图形工厂

创建一个工厂函数 create_shape(shape_type, *args),根据类型创建不同图形对象:图形工厂(函数或类)。

示例:shape_type='circle':创建圆(参数:半径);shape_type='rectangle':创建长方形(参数:长、宽)

python 复制代码
import math
# 定义圆类
class Circle:
    def __init__(self,radius):
        self.radius = radius
    def calculate_area(self): #计算面积
        area = round(math.pi*pow(self.radius,2),2)
        return area
    def calculate_circumference(self): #计算周长
        circumference = round(2*math.pi*self.radius,2)
        return circumference
# 定义长方形类
class Rectangle:
    def __init__(self,length=1,width=1): #长和宽默认为1
        self.length = length
        self.width = width
    def calculate_area(self): #计算面积
        area = self.length * self.width
        return area
    def calculate_perimeter(self): #计算周长
        perimeter = 2*(self.length + self.width)
        return perimeter
    def is_square(self): #判断是否为正方形
        return self.length == self.width
# 图形工厂  
def create_shape(shape_type,*args):
    if shape_type.lower() == 'circle':
        return Circle(args[0])
    elif shape_type.lower() == 'rectangle':
        return Rectangle(args[0],args[1])
    else:
        return '抱歉,目前支持创建圆或长方形!'
# 测试
shape1 = create_shape("Circle", 5)
print(shape1.calculate_circumference())  # 输出:31.42

shape2 = create_shape("RecTangle", 3, 4)
print(shape2.is_square())                # 输出:False

shape3 = create_shape('triangle',3,4,5)
print(shape3)                            # 抱歉,目前支持创建圆或长方形!
相关推荐
hrrrrb5 小时前
【机器学习】管道化与自动化建模
人工智能·机器学习·自动化
koo3645 小时前
李宏毅机器学习笔记36
人工智能·笔记·机器学习
jieyu11195 小时前
Python 实战:Web 漏洞 Python POC 代码及原理详解(3)
python·web安全
弗朗凌戈5 小时前
机器学习-导师优选
人工智能·python·机器学习
hans汉斯5 小时前
基于机器学习的商业银行信贷风险评估系统构建与实证研究
大数据·人工智能·爬虫·算法·yolo·机器学习·支持向量机
深度之眼5 小时前
“LSTM+时间序列异常检测”老树开新花!新玩法=发文密码,快来学呀!
人工智能·机器学习·idea
全栈探索者6 小时前
numpy基础
python·数据分析·numpy
程序员爱钓鱼6 小时前
Python编程实战 - 函数与模块化编程 - Python内置模块(math、os、sys、random等)
后端·python·ipython
Blossom.1186 小时前
把AI“灌”进奶瓶:1KB决策树让婴儿温奶器自己学会「恒温+计时」
人工智能·python·深度学习·算法·决策树·机器学习·计算机视觉