鱼C论坛

 找回密码
 立即注册
查看: 3118|回复: 15

[知识点备忘] 第062讲:类和对象(V)

[复制链接]
发表于 2022-6-3 00:46:51 | 显示全部楼层 |阅读模式
购买主题 已有 25 人购买  本主题需向作者支付 5 鱼币 才能浏览
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-4 15:12:11 | 显示全部楼层
class Animal:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say(self):
        print(f"我叫{self.name},今年{self.age}岁。")

class FlyMixin:
    def fly(self):
        print("我会飞")

class Pig(FlyMixin,Animal):
    def special(self):
        print("我的技能是")

p=Pig("大肠",5)
p.say()
p.special()
p.fly()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2022-9-27 18:20:59 | 显示全部楼层
Mixin即Mix-in,直译为混入或乱入,其实是一种设计模式,也就是利用编程语言已有的特性,针对面向对象开发过程中反复出现的问题而设计的解决方案。应用Mixin相当于打组合拳,在不修改原有类结构的基础上编写一个新的父类,使之被继承以实现新功能,这类似于游戏外挂的思路,还有点像我们之前学过的装饰器!视频以两个典型的程序为例,介绍了Mixin的基本实现逻辑,顺带复习了上节课学过的super()函数及MRO“深度优先,从左向右”的查找规则,温故知新,融会贯通!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-15 00:14:09 | 显示全部楼层
Learning...好家伙,楼层这么低,小甲鱼讲得挺好的啊。
class dis:
    def display(self,message):
        print(message)

class logger:
    def log(self,message,filename="logfile.txt"):
        with open(filename,"a") as f:
            f.write(message)

    def display(self,message):
        super().display(message)
        self.log(message)

class mysub(logger,dis):
    def log(self,message):
        super().log(message,filename="subclasslog.txt")

subclass = mysub()
subclass.display("This is a test.")
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-2 13:36:39 | 显示全部楼层
本帖最后由 Ensoleile 于 2023-1-10 00:38 编辑

MIXIN         案例源码分析 -> P159
class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say(self):
        print(f'我叫{self.name},我今年{self.age}岁。')

class FlyMixin:
    def fly(self):
        print('我还会飞~')

class Pig(FlyMixin,  Animal):
    def special(self):
        print('我的技能是拱大白菜~')

p = Pig('大肠', 5)
p.say()
p.special()
p.fly()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-1-12 20:59:25 | 显示全部楼层
打卡
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-16 22:38:47 | 显示全部楼层

红色部分self指的是实例对象本身

本帖最后由 lc88824 于 2024-1-16 22:57 编辑

红色部分self指的是实例对象本身
屏幕截图 2024-01-16 224031.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:16:06 | 显示全部楼层
这里起名不添加Mixin是不是也不影响@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:16:17 | 显示全部楼层
phTian 发表于 2024-07-01 10:16
这里起名不添加Mixin是不是也不影响@FishC


你好呀,鱼油!这个问题挺有意思的,我来给你解释一下。Mixin 就像是编程中的“调味料”,它可以给你的类添加一些额外的功能和属性。

假设你有一个基础类,比如《女巫》的食谱(这个类),可以用来做最基本的「南瓜汤」。光有南瓜汤可能有点单调,你突然灵机一动,想给汤里加点辣椒、葱花什么的,这些配料就像 Mixin 类一样,可以为你的南瓜汤类增添各种“风味”。

如果你不添加 Mixin,基础的南瓜汤还是能喝的,但要是你想让它变得与众不同、风味更丰富,那就需要 Mixin 来帮忙啦。

所以,简单来说,不加 Mixin 你的代码不会报错,但也少了一份“美味”。添加 Mixin 能让你的类变得更强大,也更加灵活。希望这个解释能让你更容易理解 Mixin 的作用,也让编程不再那么枯燥无味!

@FishC

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:19:32 | 显示全部楼层
FishC 发表于 2024-7-1 10:16
你好呀,鱼油!这个问题挺有意思的,我来给你解释一下。Mixin 就像是编程中的“调味料”,它可以给你的 ...

继续
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:20:20 | 显示全部楼层


好的,接着我们继续深入学习类和对象的知识。现在我们来看一个更实际的例子。

假设我们在编写一个文字冒险游戏,我们可能会有一个“角色”类:
class Character:
    def __init__(self, name, power):
        self.name = name
        self.power = power

    def attack(self, monster):
        print(f"{self.name}攻击了{monster.name},造成了{self.power}点伤害!")
在游戏中,我们可能还会有很多不同类型的角色,比如战士、法师、盗贼等等。这些角色虽然有很多共同的属性和方法(例如名字、力量和攻击),但是他们也可能有一些特殊的技能。

对于这种情况,我们可以使用Mixin类来添加这些特殊的技能,比如:
class StealthMixin:
    def stealth(self):
        print(f"{self.name}启动了隐身技能!")

class MageMixin:
    def magic_attack(self, monster):
        print(f"{self.name}对{monster.name}发动了魔法攻击!")
然后,我们的角色类就可以通过继承这些Mixin类来获得额外的技能:
class Rogue(StealthMixin, Character):
    pass

class Mage(MageMixin, Character):
    pass
这样,我们就可以非常灵活地为各种角色添加不同的技能,而不需要大量复制和修改代码。同时,如果我们想要添加新的技能,只需要定义一个新的Mixin类即可。

所以,你看,Mixin在编程中的作用就像乐高积木一样,可以让我们轻松地搭建起复杂的系统,而且还能保持代码的清晰和简洁!

希望这个解释能让你更深入地理解Mixin的作用,如果还有问题,随时向我提问哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:21:50 | 显示全部楼层
class Displayer:
    def display(self, message):
        print(message)
   
class Logger:
    def log(self, message, filename="logfile.txt"):
        with open(filename, "a") as f:
            f.write(message)
   
    def display(self, message):
        super().display(message)
        self.log(message)
   
class MySubClass(Logger, Displayer):
    def log(self, message):
        super().log(message, filename="subclasslog.txt")
   
subclass = MySubClass()
subclass.display("This is a test.")
课程中的代码修改成这样对结果有影响吗@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:22:06 | 显示全部楼层
phTian 发表于 2024-07-01 10:21
class Displayer:
    def display(self, message):
...


哟,小鱼油,你这是在搞一场代码大冒险啊!根据你的代码修改,这确实会对结果有影响哦。让我来详细说说:

首先,我们看一下修改后的代码结构:
class Displayer:
    def display(self, message):
        print(message)
    
class Logger:
    def log(self, message, filename="logfile.txt"):
        with open(filename, "a") as f:
            f.write(message)
    
    def display(self, message):
        super().display(message)
        self.log(message)
    
class MySubClass(Logger, Displayer):
    def log(self, message):
        super().log(message, filename="subclasslog.txt")
    
subclass = MySubClass()
subclass.display("This is a test.")

我们来看看`MySubClass`的`display`方法到底在做些什么:

1. 当你调用`subclass.display("This is a test.")`的时候,Python 会首先从`MySubClass`上找`display`方法。
2. `MySubClass`没有定义`display`方法,因此它会去继承的父类找,而`MySubClass`继承了`Logger`和`Displayer`,所以它会先从`Logger`那里找(因为`Logger`在继承列表中的顺序靠前)。
3. 在`Logger`中找到了`display`方法,这个方法调用了`super().display(message)`。

接下来,`super().display(message)`会发生什么呢?
- 由于`Logger`是第一个被检查的父类,`super()`会跳过`Logger`,去找下一个父类,也就是`Displayer`中的`display`方法。
- `Displayer`的`display`方法仅仅打印了传入的信息。

于是,当这一步执行完,你的消息已经被打印出来了。

然后是这行代码:`self.log(message)`
- 由于你使用的是`MySubClass`的实例,`self.log`会调用`MySubClass`中重写的`log`方法。
- 在`MySubClass`的`log`方法里,`super().log(message, filename="subclasslog.txt")`,这里的`super()`会调用父类`Logger`的`log`方法,但是这次它会把日志写到`subclasslog.txt`文件中。

总结一下:
- 消息先打印到了屏幕上。
- 然后,消息被记录在了`subclasslog.txt`文件中,而不是默认的`logfile.txt`文件中。

所以结论是:**是的,你的代码修改确实会对最终结果有影响!** 打印行为没有改变,但日志是写到了不同的文件!

希望我的解答能让你笑得肚子疼,嗝~(如果真的肚子疼,请立刻停止阅读,去找医生!)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:29:15 | 显示全部楼层
FishC 发表于 2024-7-1 10:22
哟,小鱼油,你这是在搞一场代码大冒险啊!根据你的代码修改,这确实会对结果有影响哦。让我来详细说说 ...

使用Mixin类的时候,类的名字中不包含Mixin字段,对结果有影响吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-1 10:29:35 | 显示全部楼层
phTian 发表于 2024-07-01 10:29
使用Mixin类的时候,类的名字中不包含Mixin字段,对结 ...


嗨,小朋友,你的问题就像是问“猪八戒戴不戴帽子,能不能镇住妖怪”一样。Mixin类的名字中不包含“Mixin”字段,对结果没有任何影响,关键在于它的功能,而不是名字。

你可以把Mixin类的名字改成其他任何东西,只要这个类的功能和方法保持不变,最终结果也不会有变化。例如:
class Displayer:
    def display(self, message):
        print(message)

# 把LoggerMixin改名为Logger,不带Mixin字段
class Logger:
    def log(self, message, filename="logfile.txt"):
        with open(filename, "a") as f:
            f.write(message)

    def display(self, message):
        super().display(message)
        self.log(message)

class MySubClass(Logger, Displayer):
    def log(self, message):
        super().log(message, filename="subclasslog.txt")

subclass = MySubClass()
subclass.display("This is a test.")

这里,你把`LoggerMixin`改名为`Logger`,但是类的功能都没有变,结果依然是:
1. 消息打印在屏幕上:"This is a test."
2. 消息被写入到`subclasslog.txt`文件中。

总结一下:
- Mixin类的命名使用了“Mixin”,只是为了让代码更具可读性,让其他开发者一眼就知道这是一个用于“混入”的类。
- 改变名字不会影响程序行为,但可能会让代码变得难以理解。所以还是建议用清晰的命名,帮助未来的你(和其他人)少费点脑细胞哦!

希望这个解释没有让你感觉像是在迷宫里转圈圈!嘻嘻,如果困惑还没扫除,继续问,我乐此不疲!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-12 17:57:50 | 显示全部楼层
最后代码复现是成功的,运行后也显示了“this is a test”,但是找不到创建的文件在哪里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 20:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表