鱼C论坛

 找回密码
 立即注册
查看: 3215|回复: 18

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

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

使用道具 举报

发表于 2022-6-25 01:28:48 | 显示全部楼层
不会英语名字不会起怎么办。每次都是abc
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 3 反对 1

使用道具 举报

 楼主| 发表于 2022-6-30 18:06:23 | 显示全部楼层
nikezhi 发表于 2022-6-25 01:28
不会英语名字不会起怎么办。每次都是abc

推荐 -> https://fanyi.baidu.com

实在不行用拼音简写也可以哈

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

使用道具 举报

发表于 2022-8-28 17:46:13 | 显示全部楼层
在类与对象第八讲里面,最后一个关于用del让对象重生的例子,请问一下self(也就是e)是怎么传进外围函数的呀?调用self.func(self),但是这个参数是怎么传进去的呀,outter()函数没有参数呀?又是怎么把self给x的呢?

点评

将self传给函数保存到x内了  发表于 2023-6-19 23:18
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-18 11:33:40 | 显示全部楼层
nikezhi 发表于 2022-6-25 01:28
不会英语名字不会起怎么办。每次都是abc
def jia(a, b):
    return a + b

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

使用道具 举报

发表于 2022-9-28 19:17:02 | 显示全部楼层
久仰Python“魔法方法”大名,现在我们终于要来揭开它的神秘面纱了!魔法方法拥有神奇而强大的功效,与众不同的“超能力”,可以让你的对象听你的!魔法方法的名称前后通常都各有两个下横线,如构造函数__init__()就是我们接触到的第一个魔法方法,能够在类实例化对象的时候自动进行调用。这节课还讲到了另外两个魔法方法:__new__()方法和__del__()方法,分别用于创建和销毁对象。其中,__new__()方法的重写通常用于两种情况,一种是在“元类”中定制类,另一种是在继承不可变数据类型时从中作梗,在实例对象创建之前进行拦截,从而达到修改不可变对象的目的;__del__()方法仅在对象被销毁,即最后一个引用消失的时候才会被自动调用。除此之外,__del__()方法还可以通过创建一个该实例的新引用来推迟其销毁,使对象重生。具体的操作方法是在对象被销毁之前将self通过某种形式(如全局变量或闭包)“送出去”,暗度陈仓,将其保存(备份)起来,这样即使对象被销毁了,我们仍可通过备份访问到它,这不禁让我们再次想起了那句名言:“有的人死了,他还活着……”
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2022-9-28 19:29:27 | 显示全部楼层
云会飞 发表于 2022-8-28 17:46
在类与对象第八讲里面,最后一个关于用del让对象重生的例子,请问一下self(也就是e)是怎么传进外围函数的 ...

self是通过内部函数inner()窃取的,__del__()在调用内部函数inner()时带参数self,故可将self保存在外部函数的变量x当中(执行“x = y”),而执行“g = f()”时由于不带参数,便可由外部函数outter()返回该self对象(执行“return x”),赋值给g,使d重生。
@小甲鱼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-2 10:19:26 From FishC Mobile | 显示全部楼层
还是不怎么理解最后一个程序执行的逻辑,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-30 22:57:26 | 显示全部楼层
多做多练即可慢慢的熟能生巧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 13:29:00 | 显示全部楼层
Learning...
class E:
    def __init__(self,name,func):
        self.name = name
        self.func = func
    def __del__(self):
        self.func(self)

        
def outter():
    x = 0
    def inner(y=None):
        nonlocal x
        if y:
            x = y
        else:
            return x
    return inner

f = outter()
e = E("小甲鱼",f)
e
<__main__.E object at 0x000001E753393CA0>
e.name
'小甲鱼'
del e
e
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    e
NameError: name 'e' is not defined. Did you mean: 'E'?
g = f()
g
<__main__.E object at 0x000001E753393CA0>
g.name
'小甲鱼'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-3 00:01:20 | 显示全部楼层
本帖最后由 Ensoleile 于 2023-1-10 00:35 编辑

魔法方法
#通过对魔法方法重写,我们就能从中作梗
#参与构建对象之前还有个__new__()方法,在__init__()之前被调用,P161
#事实上对象就是由__new__(cls[, ...])方法来创建的,所以它的第一个参数是cls,而不是self
#所以对象的诞生流程是先调用__new__()方法创建一个类的实例对象,然后将其传递给__init__()方法
#需要重写__new__()方法的情况极少,通常只有两种情况可能用到:
#一种情况是在元类中定制类,在后续课程中讲解,先按住不表
#另一种情况是在继承不可变数据类型时,可以通过重写__new__()方法进行拦截
class CapStr(str):
    def __new__(cls, string):
        string = string.upper()
        return super().__new__(cls, string)
        #不需要考虑__new__()怎么去构造对象,直接让其父类<class 'str'>去做

cs = CapStr('FishC')
print(cs) #FISHC
#这里之所以能对不可变对象进行修改,是因为我们赶在实例对象被创建前就进行了拦截,
# 然后才调用super().__new__()创建真正的实例,由于CapStr类继承自str类,所以字符串该有的方法也继承了下来
print(cs.lower()) #fishc

#__del__(self):当对象将被销毁的时候调用此方法,P162
class C:
    def __init__(self):
        print('我来了')
    def __del__(self):
        print('我走了')

c = C() #我来了
del c #我走了

#并非调用del c就一定会触发__del__()魔法方法,仅当对象被销毁时才会触发
#python中引入了垃圾回收机制garbage collection,当检测到一个对象没有任何引用的时候,才会将它销毁
c = C() #我来了
d = c
del c #没有我走了
del d #我走了

#__del__方法可以通过创建一个该实例的新引用来推迟其销毁,也被称之为对象的重生
#官方不建议,但是可以实现
#虽然对象通过del语句被删除了,但如果在对象被销毁之前将self送出去,那么对象就算是得以重生
#del是个语句,没法执行这个语句的同时,又把它的返回值赋值给另一个变量存储,即没法通过返回值的形式返回self
class D:
    def __init__(self, name):
        self.name = name
    def __del__(self):
        global x
        x = self

d = D('fishc')
print(d) #<__main__.D object at 0x000001574FDB7F70>
del d
print(x) #<__main__.D object at 0x000001574FDB7F70>
print(x.name) #fishc

#为避免污染全局变量,使用闭包
class E:
    def __init__(self, name, func):
        self.name = name
        self.func = func
    def __del__(self):
        self.func(self)

def outter():
    x = 0
    def inner(y=None):
        nonlocal x
        if y:
            x = y
        else:
            return x
    return inner

f = outter()
e = E('fishc', f)
print(e) #<__main__.E object at 0x0000024B6E6AA8E0>
print(e.name) #fishc
del e
print(f()) #<__main__.E object at 0x0000024B6E6AA8E0>
print(f().name) #fishc
#e删除后f()就是e 
#outter()返回值为inner(),f赋值为inner,c被删除时执行__del__()魔法方法
#c.func(c),即f(c),即inner(c),将c传给外层变量x,
#在再次调用f()时,y未传参,执行return x,即返回c
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

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

使用道具 举报

发表于 2023-1-29 13:18:48 From FishC Mobile | 显示全部楼层
有点看不懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-2 16:43:00 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-30 16:29:36 | 显示全部楼层
#通过对魔法方法重写,我们就能从中作梗
#参与构建对象之前还有个__new__()方法,在__init__()之前被调用,P161
#事实上对象就是由__new__(cls[, ...])方法来创建的,所以它的第一个参数是cls,而不是self
#所以对象的诞生流程是先调用__new__()方法创建一个类的实例对象,然后将其传递给__init__()方法
#需要重写__new__()方法的情况极少,通常只有两种情况可能用到:
#一种情况是在元类中定制类,在后续课程中讲解,先按住不表
#另一种情况是在继承不可变数据类型时,可以通过重写__new__()方法进行拦截
class CapStr(str):
    def __new__(cls, string):
        string = string.upper()
        return super().__new__(cls, string)
        #不需要考虑__new__()怎么去构造对象,直接让其父类<class 'str'>去做

cs = CapStr('FishC')
print(cs) #FISHC
#这里之所以能对不可变对象进行修改,是因为我们赶在实例对象被创建前就进行了拦截,
# 然后才调用super().__new__()创建真正的实例,由于CapStr类继承自str类,所以字符串该有的方法也继承了下来
print(cs.lower()) #fishc

#__del__(self):当对象将被销毁的时候调用此方法,P162
class C:
    def __init__(self):
        print('我来了')
    def __del__(self):
        print('我走了')

c = C() #我来了
del c #我走了

#并非调用del c就一定会触发__del__()魔法方法,仅当对象被销毁时才会触发
#python中引入了垃圾回收机制garbage collection,当检测到一个对象没有任何引用的时候,才会将它销毁
c = C() #我来了
d = c
del c #没有我走了
del d #我走了

#__del__方法可以通过创建一个该实例的新引用来推迟其销毁,也被称之为对象的重生
#官方不建议,但是可以实现
#虽然对象通过del语句被删除了,但如果在对象被销毁之前将self送出去,那么对象就算是得以重生
#del是个语句,没法执行这个语句的同时,又把它的返回值赋值给另一个变量存储,即没法通过返回值的形式返回self
class D:
    def __init__(self, name):
        self.name = name
    def __del__(self):
        global x
        x = self

d = D('fishc')
print(d) #<__main__.D object at 0x000001574FDB7F70>
del d
print(x) #<__main__.D object at 0x000001574FDB7F70>
print(x.name) #fishc

#为避免污染全局变量,使用闭包
class E:
    def __init__(self, name, func):
        self.name = name
        self.func = func
    def __del__(self):
        self.func(self)

def outter():
    x = 0
    def inner(y=None):
        nonlocal x
        if y:
            x = y
        else:
            return x
    return inner

f = outter()
e = E('fishc', f)
print(e) #<__main__.E object at 0x0000024B6E6AA8E0>
print(e.name) #fishc
del e
print(f()) #<__main__.E object at 0x0000024B6E6AA8E0>
print(f().name) #fishc
#e删除后f()就是e
#outter()返回值为inner(),f赋值为inner,c被删除时执行__del__()魔法方法
#c.func(c),即f(c),即inner(c),将c传给外层变量x,
#在再次调用f()时,y未传参,执行return x,即返回c
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-30 16:41:23 | 显示全部楼层
听不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-23 16:57:19 | 显示全部楼层
本帖最后由 dearfish 于 2023-6-24 01:33 编辑

type(str)  #str是类
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-30 17:19:02 | 显示全部楼层

不怎么理解最后一个程序执行的逻辑
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-27 15:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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