gpt4 book ai didi

oop - 仅实例化一个类的唯一对象

转载 作者:行者123 更新时间:2023-12-04 15:52:04 24 4
gpt4 key购买 nike

我正在尝试创建一个仅在实例化期间传入的参数是唯一组合时才创建实例的类。如果先前已传入参数组合,则返回先前已创建的实例。
我希望这个类被其他类继承,以便它们继承相同的行为。这是我第一次尝试解决方案,

要继承的基类/父类:

class RegistryType(type):
def __init__(cls, name, bases, namespace, *args):
cls.instantiated_objects = {}


class AdwordsObject(object, metaclass=RegistryType):
api = AdWordsAPI()

def __new__(cls, *args):
object_name = '-'.join(args)
if object_name in cls.instantiated_objects:
return cls.instantiated_objects[object_name]
else:
obj = super(AdwordsObject, cls).__new__(cls)
cls.instantiated_objects[object_name] = obj
# cls.newt_connection.commit()
return obj

这就是它在子类中的使用方式:
class ProductAdGroup(AdwordsObject):
# init method only called if object being instantiated hasn't already been instantiated
def __init__(self, product_name, keyword_group):
self.name = '-'.join([product_name, keyword_group])

@classmethod
def from_string(cls, name: str):
arguments = name.split('-')
assert len(arguments) == 2, 'Incorrect ad group name convention. ' \
'Use: Product-KeywordGroup'
ad_group = cls(*arguments)
return ad_group

我已经使用此设置运行了程序,但似乎每次创建 ProductAdGroup() 时都会创建一个新的字典,因此内存正在爆炸......即使程序返回了之前已经实例化的实例。

有没有什么办法解决这一问题?
谢谢!!!

最佳答案

您的代码似乎是正确的 - 上面唯一不正确的是您的 __init__无论 __new__ 返回的先前实例如何,在实例化一个新类时总是会调用该方法。或不。

因此,如果您在 __init__ 中创建额外的对象方法,这可能是您的内存泄漏的原因 - 但是,如果您将这些新对象绑定(bind)到实例(自身),它们应该只是覆盖以前在同一个地方创建的对象 - 它们会被释放。 .在此处发布的代码中,self.name 会发生这种情况。 - 可能是你真正的__init__做更多的事情,并将新对象关联到实例以外的其他地方(例如,将它们附加到列表中)。如果您的 __init__方法如图所示,在您提供的代码中,您的内存增长的原因并不明显。

作为一个额外的建议,但与您所涉及的问题无关,我补充说您根本不需要元类。

只需检查是否存在 cls.instantiated_objects __new__ 中的字典方法本身。不编写不需要的元类将简化您的代码库,如果您的类层次结构发生演变,可以避免元类冲突,如果您的元类上的代码比您在此处显示的更多,甚至可能会消除您的问题。

基类 __new__方法可以重写如下:

class AdwordsObject(object):
def __new__(cls, *args):
if not cls.__dict__.get("instantiated_objects"):
cls.instantiated_objects = {}
name = '-'.join(args)
if name in cls.instantiated_objects:
return cls.instantiated_objects[name]
instance = super().__new__(cls)
cls.instantiated_objects[name] = instance
return instance

并且不再需要自定义元类。

关于oop - 仅实例化一个类的唯一对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45511976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com