You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类实例丢失疑问:create_object创建的实例为何无法用object2访问?

问题:类实例创建后无法通过指定变量访问的疑惑

我正在准备Python考试,练习类与类方法时遇到了一个问题:我创建了一个类实例,它应该存在于类的相关集合中,但却无法通过object2变量获取它。以下是我的代码:

class Watch:
    instances = []
    def __init__(self, model):
        self.model = model
        self.eng = ""
        self.__class__.instances.append(self.model)  # 注意:这里存的是型号字符串,不是实例本身
    @classmethod
    def create_new_watch(cls, model, eng):
        if eng.isalnum() and len(eng) < 40:
            watch = cls(model)
            watch.eng = eng
        else:
            raise ValueError("Invalid engraving")
        if len(watch.eng) > 0:
            print("Your new watch model {} was created".format(watch.model))
            print("Your new watch will have the following engraving {}".format(watch.eng))
        else:
            print("Your new watch model {} was created".format(watch.model))
        return watch

object1 = Watch.create_new_watch("model S", "Newengraving")

def create_object(object2, model, eng):
    try:
        object2 = Watch.create_new_watch(model, eng)
        print(object2)
        print(isinstance(object2, Watch))
    except ValueError as e:
        print(e)
    else:
        print("the object was successfully created")

create_object("Watch4", "modello T", "Anotherengraving")

# 这部分正常,object1是Watch的实例
print(isinstance(object1, Watch))

# 这里报错说object2未定义
print(isinstance(object2, Watch))

# 但类里应该有两个实例,为什么会报错?
print(Watch.__dict__)

我的疑问是:object1是有效的Watch类实例,isinstance(object1, Watch)返回True,但调用isinstance(object2, Watch)时却报错,尽管类中已存在两个实例。请问通过create_object函数创建的第二个实例是以什么名称存在的?


解答

1. 为什么object2会报错?

核心问题是变量作用域:你在create_object函数里的object2是局部变量,它只存在于函数执行的过程中。函数结束后,这个局部变量就会被Python的垃圾回收机制处理,全局作用域里根本没有名为object2的变量,所以执行print(isinstance(object2, Watch))时会抛出NameError,提示变量未定义。

另外,你调用create_object("Watch4", "modello T", "Anotherengraving")时传的第一个参数"Watch4"完全没用——函数里直接把object2重新赋值为新创建的实例,原来的参数值被覆盖了,这个参数纯属多余,反而容易误导你以为它和全局的object2有关联。

2. 第二个实例的存在形式

你通过create_object创建的第二个实例,在全局作用域没有绑定任何变量名称。它确实被创建出来了,也被函数里的局部变量object2引用过,但函数执行结束后,这个局部引用消失;再加上你当前的Watch.instances存的是self.model(型号字符串)而非实例本身,所以没有其他地方持有这个实例的引用,Python会自动回收它。

顺便提个小问题:你的Watch.instances列表里添加的是self.model(型号字符串),而不是self(实例对象)。所以你看到Watch.__dict__里的instances有两个元素,那是两个型号字符串,不是实例本身。如果要让instances保存实例,需要把__init__里的代码改成:

self.__class__.instances.append(self)

3. 如何在全局访问这个实例?

如果想在全局作用域获取这个实例,需要让create_object函数返回它,然后在调用时赋值给全局变量:

# 修改函数,去掉多余的object2参数,返回创建的实例
def create_object(model, eng):
    try:
        watch_instance = Watch.create_new_watch(model, eng)
        print(watch_instance)
        print(isinstance(watch_instance, Watch))
    except ValueError as e:
        print(e)
        return None  # 出错时返回None
    else:
        print("the object was successfully created")
        return watch_instance

# 调用函数并赋值给全局的object2
object2 = create_object("modello T", "Anotherengraving")

# 现在就能正常检查了
print(isinstance(object2, Watch))

这样,object2就会在全局作用域绑定到新创建的实例,你就能正常访问它了。


内容的提问来源于stack exchange,提问作者Tommy D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:47:54