首页 > 编程语言 >Python基础学习(十)面向对象编程(基础)

Python基础学习(十)面向对象编程(基础)

时间:2024-11-02 18:16:17浏览次数:6  
标签:__ name Python self 基础 面向对象编程 print age def

代码获取:https://github.com/qingxuly/hsp_python_course
完结版:Python基础学习(完结版)

面向对象编程(基础)

类与对象

类与实例的关系
  • 类与实例的关系示意图

image-20240803165751137

image-20240803170126439

快速入门—面向对象的方式解决养猫问题
# 定义一个猫类,age, name, color 是属性,或者称为成员变量
# Cat 类 就是你自己定义的一个新类型

# 定义 Cat 类
class Cat:
    # age, name, color 是属性
    age = None  # 年龄属性
    name = None  # 名字属性
    color = None  # 颜色属性


# 通过 Cat 类,创建实例(实例对象/对象)
cat1 = Cat()

# 通过对象名.属性名 可以给各个属性赋值
cat1.name = "小白"
cat1.age = 2
cat1.color = "白色"

# 通过对象名.属性名,可以访问到属性
print(f "cat1 的信息为:name: {cat1.name} age {cat1.age} color {cat1.color}")

# 小结:通过上面的 oop 解决问题,可以更好地管理小猫的属性
类和对象的区别和联系
  • 类是抽象的,概念的,代表一类事物,比如人类,猫类,…,即它是数据类型。
  • 对象是具体的,实际的,代表一个具体事物,即是实例。
  • 类是对象的模板,对象是类的一个个体,对应一个实例。
对象在内存中的存在形式
  • 内存分析图

image-20240803171539253

属性/成员变量
  • 基本介绍
    • 类中定义的属性(变量),我们成为:成员变量。
    • 属性是类的一个组成部分,一般是字符串、数值,也可以是其它类型(list、dict等),比如前面定义Cat类的name、age就是属性。
  • 注意事项和细节说明
    • 属性的定义语法同变量,实例:属性名 = 值,如果没有值,可以赋值None。
      • None 是python的内置常量,通常被用来代表空值的对象。
    • 如果给属性指定的有值,那么创建的对象属性就有值。
# 定义 Cat 类
class Cat:
    # age, name, color 是属性
    age = 2  # 年龄属性
    name = "小白"  # 名字属性
    color = "白色"  # 颜色属性


# 创建对象
cat1 = Cat()

print(f "age:{cat1.age}, name:{cat1.name}, color:{cat1.color}")
类的定义和使用
  • 如何定义类
class 类名:
	属性...
    行为...
    
# class 是关键字,表示后面定义的是类。
# 属性:定义在类中的变量(成员变量)
# 行为:定义在类中的函数(成员方法)
  • 如何创建对象
对象名 = 类名()

# 举例
cat = Cat()
  • 如何访问属性
对象名.属性名

# 举例
cat.name
对象的传递机制
class Person:
    age = None
    name = None


p1 = Person()
p1.age = 10
p1.name = "小明"

p2 = p1
print(p2.age)
print(f "id(p1.name): {id(p1.name)}, id(p2.name): {id(p2.name)}")

image-20240803173238405

a = Person()
a.age = 10
a.name = "jack"

b = a
print(b.name)
b.age = 200
b = None
print(a.age)
print(b.age)  # AttributeError: 'NoneType' object has no attribute 'age'

image-20240803173915701

对象的布尔值

  • Python一切皆为西,所有对象都有一个布尔值,可以通过内置函数bool()可以获取对象的布尔值。
  • 下面对象的布尔值为False
    • False、数值0、None、空字符串、空列表、空字典、空元组、空集合。
print("---下面对象的布尔值为 False---")
print(bool(False))
print(bool(0))
print(bool(None))
print(bool(""))
print(bool([]))
print(bool(()))
print(bool({}))
print(bool(set()))
# 因为所有对象都有一个布尔值,所有有些代码直接使用对象的布尔值做判断
content = "hello"
if content:
    print(f "hi {content}")
else:
    print("空字符串")


lst = [1, 2]
if lst:
    print(f "lst {lst}")
else:
    print("空列表")

成员方法

基本介绍
  • 类出来有一些属性外,还会有一些行为,比如人类有年龄、姓名等属性,我们人类还有一些行为,比如:可以说话、跑步、…,通过学习,还可以做算术题。这时就要用成员方法才能完成。
class 类名:
    属性...
    行为...
    
# 类中定义的行为(函数),我们成为:成员方法/方法
成员方法的定义和使用
  • 成员方法的定义
    • 在类中定义成员方法和前面学习过的定义函数,基本是一样的(原理和运行机制是一样的),但是还是有点不同(形式上有不同)。
def 方法名(self, 形参列表):
    方法体

# 在方法定义的参数列表中,有一个 self
# self 是定义成员方法时,需要写上的
# self 表示当前对象本身
# 当我们通过对象调用方法时,self 会隐式的传入
# 在方法内部,需要使用 self,才能访问到成员变量
  • 案例演示
class Person:
    age = None
    name = None

    # 成员方法
    def hi(self):
        print("hi, python")

    def cal01(self):
        result = 0
        for i in range(1, 1001):
            result += i
        print(f "result: {result}")

    def cal02(self, n):
        result = 0
        for i in range(1, n + 1):
            result += i
        print(f "result: {result}")

    def get_sum(self, n1, n2):
        return n1 + n2


# 测试
p = Person()

p.hi()
p.cal01()
p.cal02(10)
print(p.get_sum(10, 20))
使用细节
  • python也支持对象动态的添加方法
# 函数
def hi():
    print("hi, python")


# 定义类
class Person:
    age = None
    name = None

    def ok(self):
        pass


# 创建对象 p、p2
p = Person()
p2 = Person()

# 动态地给 p 对象添加方法 m1,注意:只是针对 p 对象添加方法
# m1 是你新增加的方法的名称,由程序员指定名称
# 即 m1 方法和函数 hi 关联起来,当调用 m1 方法时,会执行 hi 函数
p.m1 = hi

# 调用 m1(即 hi)
p.m1()

print(type(p.m1), type(hi))  # <class 'function'> <class 'function'>
print(type(p.ok))  # <class 'method'>


# 因为没有动态的给 p2 添加方法,会报错
p2.m1()  # AttributeError: 'Person' object has no attribute 'm1'

self

访问对象的属性/成员变量
class Cat:
    name = "波斯猫"
    age = 2

    def info(self, name):
        print(f "name: {name}")  # 加菲猫
        # 通过 self.属性名 可以访问对象的属性/成员变量
        print(f "属性 name:{self.name}")  # 波斯猫


cat = Cat()
cat.info("加菲猫")
基本介绍
  • 基本语法
def 方法名(self, 形参列表):
    方法体

# 在方法定义的参数列表中,有一个 self
# self 是定义方法时,需要写上的,如果不写,则需要使用 @staticmethod 标注,否则会报错
# 将方法转换为静态方法:https://docs.python.org/zh-cn/3/library/functions.html#staticmethod
class Dog:
    name = "藏獒"
    age = 2

    def info(self, name):
        print(f "name: {name}")

    # @staticmethod 可以将普通方法转换为静态方法。
    # 如果是一个静态方法,可以不带 self
    # 静态方法的调用形式有两种:通过对象调用、通过类名调用
    @staticmethod
    def ok():
        print("ok()...")


dog = Dog()
dog.info("德牧")

# 通过对象调用
dog.ok()
# 通过类名调用
Dog.ok()
  • self 表示当前对象本身,简单的说,哪个对象调用,self 就代表哪个对象。
class Dog:
    name = "藏獒"
    age = 2

    def hi(self):
        print(f "hi self: {id(self)}")


dog2 = Dog()
print(f "dog2: {id(dog2)}")
dog2.hi()

dog3 = Dog()
print(f "dog3: {id(dog3)}")
dog3.hi()
  • 当我们通过对象调用方法时,self 会隐式的传入。

  • 在方法内部,要访问成员变量和成员方法,需要使用 self。

# 在方法内部,要访问成员变量和成员方法,需要使用 self。
class Dog:
    name = "藏獒"
    age = 2

    def eat(self):
        print(f "{self.name} 饿了...")

    def cry(self, name):
        print(f "{name} is crying")
        print(f "{self.name} is crying")
        self.eat()
        # 不能直接调用
        # eat()


dog = Dog()
# 修改 dog 对象的属性 name
dog.name = "中华田园犬"
dog.cry("金毛")
  • 练习题
class Person:
    name = None
    age = None

    def compare_to(self, other):
        # 名字和年龄都一样,就返回 True,否则返回 False
        return self.name == other.name and self.age == other.age


p1 = Person()
p1.name = "jack"
p1.age = 3
p2 = Person()
p2.name = "jack"
p2.age = 3

print(p1.compare_to(p2))

对象作为参数传递

  • 对象的传参机制
class Person:
    name = None
    age = None


# 分析对象作为参数传递到函数/方法的机制
def f1(person):
    print(f "②person 的地址:{id(person)}")
    person.name = "james"
    person.age += 1


# 创建对象 p1
p1 = Person()

p1.name = "jordan"
p1.age = 21

print(f "①p1 的地址:{id(p1)} p1.name: {p1.name} p1.age: {p1.age}")
f1(p1)

print(f "③p1 的地址:{id(p1)} p1.name: {p1.name} p1.age: {p1.age}")
  • 示意图

image-20240805211700331

作用域

  • 在面向对象编程中,主要的变量就是成员变量(属性)和局部变量。
class Cat:
    # 属性(成员变量)
    name = None
    age = None
    
    # n1, n2, result 就是局部变量
    def cal(self, n1, n2):
        result = n1 + n2
        print(f "result = {result}")
  • 我们说的局部变量,一般指在成员方法中定义的变量。
  • 作用域的分类:属性作用域为整个类,比如 Cat类:cry eat 等方法使用属性。
class Cat:
    # 属性
    name = None
    age = None
    
    # n1, n2, result 就是局部变量
    def cal(self, n1, n2):
        result = n1 + n2
        print(f "cal() 使用属性 name {self.name}")
    
    def cry(self):
        print(f "cry() 使用属性 name {self.name}")
    
    def eat(self):
        print(f "eat() 使用属性 name {self.name}")

        
cat = Cat()
cat.cal(10, 20)
cat.cry()
cat.eat()
  • 局部变量:也就是方法中定义的变量,作用域是它在方法中。
  • 属性和局部变量可以重名,访问时带上 self,表示访问的属性,没有带 self,则是访问局部变量。
class Cat:
    # 属性
    name = None
    age = None
    
	def hi(self):
        name = "皮皮"
        print(f "name is {name}")
        print(f "self.name is {self.name}")


cat = Cat()
cat.name = "小咪"
cat.hi()

构造方法

基本介绍
def __init__(self, 参数列表):
    代码...
  • 在初始化对象时,会自动执行__init__方法
  • 在初始化对象时,传入的参数,自动传递给__init__方法。
  • 构造方法是python预定义的,名称是__init__,注意init前后都有两个_
# 在初始化对象时,会自动执行 __init__ 方法
class Person:
    name = None
    age = None

    # 构造方法/构造器
    # 构造方法是完成对象的初始化任务
    def __init__(self, name, age):
        print(f "__init__ 执行了 {name} {age}")
        # 把接收到的 name 和 age 赋给属性(name, age)
        # self 就是你当前创建的对象
        print(f "self id: {id(self)}")
        self.name = name
        self.age = age


# 创建对象
p1 = Person("kobe", 20)
print(f "p1 id: {id(p1)}")
print(f "p1 的信息: {p1.name} {p1.age}")

p2 = Person("tim", 30)
print(f "p2 id: {id(p2)}")
print(f "p2 的信息: {p2.name} {p2.age}")
注意事项和使用细节
  • 一个类只有一个__init__方法,即使你写了多个,也只有最后一个生效。
class Person:
    name = None
    age = None

    def __init__(self, name, age):
        print(f "__init__ 执行了... 得到了{name} {age}")
        self.name = name
        self.age = age

    def __init__(self, name):
        print(f " __init__ 执行了~~ 得到了{name}")
        self.name = name


# TypeError: Person.__init__() takes 2 positional arguments but 3 were given
# p1 = Person("tim", 20)

# 后面的 __init__()生效
p1 = Person("tim")
print(f "p1 的 name ={p1.name} age ={p1.age}")
# 为了代码简洁,我们也可以通过 __init__ 动态的生成对象属性
# python 可以动态的生成对象属性。
class Person:
    def __init__(self, name, age):
        print(f "__init__ 执行了... 得到了{name} {age}")
        # 将接收到的 name 和 age 赋给当前对象的 name 和 age 属性
        # python 支持动态生成对象属性
        self.name = name
        self.age = age


p1 = Person("tim", 30)
print(f "p1 的 name ={p1.name} age ={p1.age}")
  • 构造方法不能有返回值。
class Person:
    def __init__(self, name, age):
        print(f "__init__ 执行了... 得到了{name} {age}")
        self.name = name
        self.age = age
        return "hello"  # TypeError: __init__() should return None, not 'str'

练习

1、编写A01,定义方法max_lst,实现求某个float 列表list = [1.1, 2.9, -1.9, 67.9]的最大值,并返回。

# 1、编写 A01,定义方法 max_lst,实现求某个 float 列表 list = [1.1, 2.9, -1.9, 67.9] 的最大值,并返回。
"" "
    思路分析
    1. 类名:A01
    2. 方法:max_lst(self, lst), 功能:返回列表的最大值
"" "


class A01:
    def max_lst(self, lst):
        return max(lst)


# 测试
a = A01()
print("最大值:", a.max_lst([1.1, 2.9, -1.9, 67.9]))

2、编写类Book,定义方法update_price,实现更改某本书的价格,具体:如果价格>150,则更改为150,如果价格>100,更改为100,否则不变。

# 2、编写类 Book,定义方法 update_price,实现更改某本书的价格,具体:如果价格 > 150,则更改为 150,如果价格 > 100,更改为 100,否则不变。
"" "
    思路分析:
    类名:Book
    属性:name, price
    构造器:__init__(self, name, price)
    方法:update_price, 功能:如果价格 > 150,则更改为 150,如果价格 > 100,更改为 100,否则不变。
"" "


class Book:

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

    def update_price(self):
        # 如果价格 > 150,则更改为 150,如果价格 > 100,更改为 100,否则不变。
        if self.price > 150:
            self.price = 150
        elif self.price > 100:
            self.price = 100

    def info(self):
        # 输出书籍的信息
        print(f "书的信息:{self.name} {self.price}")


book = Book("天龙八部", 99)
book.info()
book.update_price()
book.info()

3、定义一个圆类Circle,定义属性:半径,提供显示圆周长功能的方法,提供显示圆面积的方法。

# 定义一个圆类 Circle,定义属性:半径,提供显示圆周长功能的方法,提供显示圆面积的方法。

"" "
    思路分析:
    类名:Circle
    属性:radius
    构造器:__init_(self, radius)
    方法:len(self) 显示圆周长
    方法:area(self) 显示圆面积
"" "
import math


class Circle:
    def __init__(self, radius):
        self.radius = radius

    def len(self):
        len = 2 * math.pi * self.radius
        print("周长:", round(len, 2))

    def area(self):
        area = math.pi * (self.radius ** 2)
        print("面积:", round(area, 2))


# 测试
circle = Circle(5)
circle.len()
circle.area()

4、编程创建一个Cal计算类,在其中定义2个成员变量表示两个操作数,定义四个方法实现求和、差、乘、商(要求除数为0的话,要提示)并创建对象,分别测试。

# 编程创建一个 Cal 计算类,在其中定义 2 个成员变量表示两个操作数,定义四个方法实现求和、差、乘、商(要求除数为 0 的话,要提示)并创建对象,分别测试
"" "
    思路分析:
    类名:Cal
    属性:num1, num2
    构造器/构造方法:__init__(self, num1, num2)
    定义四个方法实现求和 def sum(), 求差 def minus(), 求积 def mul(), 求商 def div()
    商(要求除数为 0 的话,要提示)
"" "


class Cal:
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

    def sum(self):
        return self.num1 + self.num2

    def minus(self):
        return self.num1 - self.num2

    def mul(self):
        return self.num1 * self.num2

    def div(self):
        if self.num2 == 0:
            print("num2 不能为 0")
        else:
            return self.num1 / self.num2


cal = Cal(1, 0)
print("和 =", cal.sum())
print("差 =", cal.minus())
print("积 =", cal.mul())
print("商 =", cal.div())

5、定义Music类,里面有音乐名name,音乐时长times属性,并有播放play功能,和返回本身属性信息的方法get_info。

# 定义 Music 类,里面有音乐名 name,音乐时长 times 属性,并有播放 play 功能,和返回本身属性信息的方法 get_info
"" "
    思路分析:
    类名:Music
    属性:name, times
    构造器:__init__(self, name, times)
    方法:play, get_info
"" "


class Music:
    def __init__(self, name, times):
        self.name = name
        self.times = times

    def play(self):
        print(f "音乐名 {self.name} 正在播放中... 时长为 {self.times}")

    def get_info(self):
        return f "音乐的信息: name:{self.name} times:{self.times}"


# 测试
music = Music("月光曲", 300)
music.play()
print(music.get_info())

6、分析下列代码输出结果。

class Demo:
    i = 100

    def m(self):
        self.i += 1
        j = self.i
        print("i =", self.i)
        print("j =", j)


d1 = Demo()
d2 = d1
d2.m()

print(d1.i)
print(d2.i)

"" "
输出结果:
i = 101
j = 101
101
101
"" "

7、石头剪刀布游戏,0表示石头,1表示剪刀,2表示布。

import random


class Tom:
    def __init__(self):
        self.wins = 0
        self.losses = 0
        self.choices = ['石头', '剪刀', '布']

    def play(self):
        user_choice = int(input("请输入你的选择(0 = 石头,1 = 剪刀,2 = 布):"))
        if user_choice not in [0, 1, 2]:
            print("输入错误,请输入 0、1 或 2。")
            return

        computer_choice = random.randint(0, 2)
        print(f "Tom 的选择是:{self.choices [user_choice]},电脑的选择是:{self.choices [computer_choice]}")

        if user_choice == computer_choice:
            print("平局!")
        elif (user_choice == 0 and computer_choice == 1) or \
                (user_choice == 1 and computer_choice == 2) or \
                (user_choice == 2 and computer_choice == 0):
            print("Tom 赢了!")
            self.wins += 1
        else:
            print("Tom 输了!")
            self.losses += 1

    def show_scores(self):
        print(f "Tom 的赢的次数:{self.wins},输的次数:{self.losses}")


# 使用示例
tom = Tom()
tom.play()
tom.play()
tom.show_scores()

欢迎关注我的博客,如有疑问或建议,请随时留言讨论。

标签:__,name,Python,self,基础,面向对象编程,print,age,def
From: https://blog.csdn.net/qingxuly/article/details/143454238

相关文章

  • 推荐5个超级实用的 Python 模块,不知道就out啦!
    正文Python标准库有超过200个模块,程序员可以在他们的程序中导入和使用。虽然普通程序员对其中许多模块都有一些经验,但很可能有一些好用的模块他们仍然没有注意到。我发现其中许多模块都包含了在各个领域都非常有用的函数。比较数据集、协作其他函数以及音频处理等都可以仅......
  • [python]Gunicorn加持,轻松提升Flask超7倍性能
    前言之前学习和实际生产环境的flask都是用app.run()的默认方式启动的,因为只是公司内部服务,请求量不高,一直也没出过什么性能问题。最近接管其它小组的服务时,发现他们的服务使用Gunicorn+Flask的方式运行的,本地开发用的gevent的WSGIServer。对于Gunicorn之前只是耳闻,没实际用过,正......
  • PyCharm 2024.1 解锁版 (Python集成开发IDE)详细安装步骤
    分享文件:PyCharm2024.1解锁版(Python集成开发IDE)链接:https://pan.xunlei.com/s/VOAa_CiVVvZnyQgLfpmCIOABA1提取码:cx4h安装步骤1、下载解压后点击如下进行安装2、选择安装路径3、默认勾选将PyCharm创建桌面快捷方式4、默认,点击【安装】5、安装中,耐心等待2-5分......
  • Python自动化运维:技能掌握与快速入门指南
    #编程小白如何成为大神?大学生的最佳入门攻略#在当今快速发展的IT行业中,Python自动化运维已经成为了一个不可或缺的技能。本文将为您详细介绍Python自动化运维所需的技能,并提供快速入门的资源,帮助您迅速掌握这一领域。必备软件工具1.Python与PyCharmPython和PyCharm是自动......
  • Python 函数综合案例
    设计格黑娜学院银行ATM定义一个全局变量:money,用来记录银行卡余额(默认5000000)定义一个全局变量:name,用来记录客户姓名(启动程序时输入)定义如下的函数:查询余额函数存款函数取款函数主菜单函数要求.程序启动后要求输入客户姓名.查询余额,存款,取款后都会返回主菜单.......
  • 【docker】—— 部署python项目
    使用docker部署python项目这里默认已经安装好docker并进行了相关配置,只演示使用docker打包并部署一个简单的python项目。更多docker基本操作参考:【docker】——docker常用操作下面是准备好的项目和程序:项目结构:项目:DOCKER_PYTHON_TESE文件:main.ipynb代码如下:#......
  • 机器学习入门基础----白板推导笔记输出
    为了能够建立知识学习后输出体系,开设这个系列,旨在通过记录博客输出学习到的机器学习内容,笔者所学为B站upshuhuai008白板推导系列,记录可能比不上原创,也可能有没理解不严谨的地方,请善意指正。感兴趣的可以去看UP白板-------------------------------------------------------------......
  • python - 小袁口算ocr
    按照模拟器位置捕捉截图,使用paddleocr识别数字后比较大小importpyautogui,timefrompaddleocrimportPaddleOCRpaddleocr=PaddleOCR(lang='en',show_log=False,use_angle_cls=True)defcapture_screenshot(region=None):img=pyautogui.screenshot(region=regio......
  • 学习python的第十一天
    今天学习了正则有以下思维导图 对于以上内容,有以下笔记,以及关于元字符的图importfunctools#re.findallimportre#a="python12314534564java"#anqi=re.findall("123",a)#(匹配规则,数据)#print(anqi)#re.match是从一开始就开始匹配#print(re.match("python"......
  • python脚本结合计算引擎快速获取亚马逊的父ASIN并保存到数据库
    按照亚马逊的规则,一个ASIN只能有一个父ASIN,在某些情况下不得分析asin的所属变体父asin是否同一个。Python代码。  importop_data_web_hookaswebhooktable_id_dp="xxxx"defget_parent_asin_by_page_source(res):ifresisNone:return""try:......