鱼C论坛

 找回密码
 立即注册
查看: 3115|回复: 7

[已解决]python 如何判断对象是否存在

[复制链接]
发表于 2022-11-2 20:28:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#创建两个对象放入列表中
f1=Fisch()
f2=Fisch()

list1=[]
list1.append(f1)
list1.append(f2)
list1
[<__main__.Fisch object at 0x0000016AA3006AA0>, <__main__.Fisch object at 0x0000016AA3007820>]

del f2

list1
[<__main__.Fisch object at 0x0000016AA3006AA0>, <__main__.Fisch object at 0x0000016AA3007820>]

创建了两个对象之后放入列表中
如何手动销毁对象,如何判断list存放的对象是否销毁
del后list1中的数据没有变化
最佳答案
2022-11-2 23:31:54
本帖最后由 jackz007 于 2022-11-3 00:15 编辑

        很简单,对于 Python 语言来说,要判断一个对象是否存在,那就加上 try 直接访问它,如果不出错,那就是还存在,否则,当然就是不存在喽。
a = [1 , 2 , 3]
b = a
del(a)
try:
    c = a
    print("a 存在")
except:
    print("a 不存在")
try:
    c = b
    print("b 存在")
except:
    print("b 不存在")
        运行实况:
D:\[00.Exerciese.2022]\Python>python x.py
a 不存在
b 存在

D:\[00.Exerciese.2022]\Python>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-2 20:37:19 From FishC Mobile | 显示全部楼层
本帖最后由 hrpzcf 于 2022-11-2 20:45 编辑

del一个对象并不会立即销毁它,只会使引用计数减1,当引用计数为0时,对象才会被销毁。
当你
f1=Fisch()
f2=Fisch()
时,两个Fisch对象的引用计数分别为1,然后
list1.append(f1)
list1.append(f2)
后,两个Fisch对象的引用计数分别为2,你del f2后,第二个创建的Fisch对象的引用计数变为1(少了f2的对它引用,还剩下list1对它的引用)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-2 20:45:59 | 显示全部楼层
hrpzcf 发表于 2022-11-2 20:37
del一个对象并不会立即销毁它,只会使引用计数减1,当引用计数为0时,对象才会被销毁。
当你
f1=Fisch()
...

如何手动代码销毁对象?》
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-2 21:18:43 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-11-2 21:36 编辑

哈哈,因为 del x 的本质就不是 "删除对象", 而是"解除绑定"。

怎么理解这个解除绑定呢? —— 举个有点残酷的例子吧:
    假设你对象(女朋友)和你分手了,这就是"解除绑定",但 分手之前 或许她就已经和别的小白脸勾搭上了,甚至是多个勾搭上了。。
    也就是 del you 解除了你的绑定后,她还存在若干个 "绑定/引用关系",即reference>0,根据垃圾回收机制,它还没被回收,还没销毁。。

或者从代码上,更直观地说,del bf 是从命名空间(globals()或locals()字典)里 将该 bf字符名移除(变回未加定义的),
当你 再使用时,就会报错,因为绑定关系已经不存在,"bf"的名字也就无法在命名空间里找到。 比如:
f1, f2 = F(), F()
ls = [f1, f2]
sys.getrefcount(ls)  # ls这名字所绑定的对象的引用总数。 注:本来应该是1个,但getrefcount函数执行时,形参与实参会有一个临时的局部绑定,所以"通常总会多一个"(见官方说明)
2
sys.getrefcount(f1)   # f1所绑定的对象的引用总数(数一数:f1-->F_obj_1, ls[0]-->F_obj_1, getrefcount的形参object-->F_obj_1, 一共3个绑定/引用关系)
3
globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, 'F': <class '__main__.F'>, 'f1': <__main__.F object at 0x00000166761427A0>, 'f2': <__main__.F object at 0x00000166761427D0>, 'ls': [<__main__.F object at 0x00000166761427A0>, <__main__.F object at 0x00000166761427D0>]}

del f1
globals()   # 已经看不见 f1 了(解除f1的绑定),但 ls[0]位置上还是指向、绑定着 原本f1所绑定的对象
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, 'F': <class '__main__.F'>, 'f2': <__main__.F object at 0x00000166761427D0>, 'ls': [<__main__.F object at 0x00000166761427A0>, <__main__.F object at 0x00000166761427D0>]}
f1
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    f1
NameError: name 'f1' is not defined. Did you mean: 'f2'?       # 看,f1 这位男友,已经被对象给"甩了"。。

# ps: 那要怎么 摧毁这个可恶的 女人(对象)呢?  ——  搞坏、破坏掉她和其他所有男人的关系!把她丢到"垃圾回收"里去! 哈哈
del ls[0]    


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

使用道具 举报

发表于 2022-11-2 21:51:52 | 显示全部楼层
zy8818 发表于 2022-11-2 20:45
如何手动代码销毁对象?》



可以认真看看这篇文章,应该对你有所帮助:

http://c.biancheng.net/view/2371.html

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

使用道具 举报

发表于 2022-11-2 22:01:03 | 显示全部楼层
本帖最后由 hrpzcf 于 2022-11-2 22:04 编辑
zy8818 发表于 2022-11-2 20:45
如何手动代码销毁对象?》


除了删除所有引用外没有别的办法了(在我的知识范围内),gc.collect也只是在引用计数的基础上工作。
我猜你是想在一个地方删除某个对象,另一个地方的同一个对象也会被删除,那你为什么不直接使用一个列表来做桥梁呢?完全能达到这个要求:
class Fish:
    pass


obj_list = []


def afunc():
    obj_list.extend([Fish(), Fish()])
    print(f"obj_list in afunc: {obj_list}")


def bfunc():
    del obj_list[1]
    print(f"obj_list in bfunc: {obj_list}")


def cfunc():
    print(f"obj_list in cfunc: {obj_list}")


afunc()
bfunc()
cfunc()

甚至不需要把列表创建为一个全局列表,只需把列表作为参数传给别的函数、方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-2 22:34:26 From FishC Mobile | 显示全部楼层
浅拷贝和深拷贝
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-2 23:31:54 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-11-3 00:15 编辑

        很简单,对于 Python 语言来说,要判断一个对象是否存在,那就加上 try 直接访问它,如果不出错,那就是还存在,否则,当然就是不存在喽。
a = [1 , 2 , 3]
b = a
del(a)
try:
    c = a
    print("a 存在")
except:
    print("a 不存在")
try:
    c = b
    print("b 存在")
except:
    print("b 不存在")
        运行实况:
D:\[00.Exerciese.2022]\Python>python x.py
a 不存在
b 存在

D:\[00.Exerciese.2022]\Python>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-25 19:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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