【问题标题】:Is type(name, bases, dict) could be used to create instance(object of class), for example inside Singleton类型(名称、基础、字典)是否可用于创建实例(类的对象),例如在 Singleton 中
【发布时间】:2018-04-22 02:54:46
【问题描述】:

所以有object.__new__(cls)super().__new__(cls)函数可以用来创建实例,但是我可以用type(name, bases, dict)(*args, **kwargs)来创建实例吗?

class Singleton(object):

  instance = None

  def __init__(self, *args, **kwargs):
    pass

  def __new__(cls, *args, **kwargs):
    if isinstance(cls.instance, type(None)):
      mcls = cls.__class__
      cls.instance = type(mcls.__name__, mcls.__bases__, dict(cls.__dict__))(*args, *kwargs)

    return cls.instance

s = Singleton()
print(s)

【问题讨论】:

  • 你为什么要这样做?
  • 实验:)
  • 嗯,错误非常明确,您将 mappingproxy 而不是 dict 传递给参数 3,dict(mcls.__dict__) 也是如此。请注意,我正在尝试找出另一个错误...
  • 谢谢,我更改了 dict(mcls.__dict__) 结果:TypeError: type qualname must be a str, not getset_descriptor
  • type('MyClass',(),{})()

标签: python python-3.x metaclass


【解决方案1】:

所以我找不到将__new__ 方法保留在cls.__dict__ 中的方法,它会导致递归,所以我在创建类之前将其删除。

class FooMixin(object):
  def print_somth(self):
    print('smth....')


class Singleton(FooMixin):

  instance = None

  def __new__(cls, *args, **kwargs):
    if cls.instance is None:
      temp = dict(cls.__dict__)
      del temp['__new__']
      temp['test'] = 100
      cls.instance = type('Singleton', cls.__bases__, temp)(*args, **kwargs)
    return cls.instance

s = Singleton()
print(s.test, s.print_somth())

【讨论】:

  • 要处理递归错误,只需从作为第三个参数传递的dict 中删除__new__
  • 您意识到,顺便说一句,__call__ 从未真正被调用,对吧?即,您在__call__ 中写的任何内容都没有做任何事情...
  • 这不是单件,这是单件工厂。
  • @Rawing 好吧,甚至不是这样。 Singleton.instance 始终是 None
  • 你为什么使用cls.__class__.__bases__?为什么不只是type.__bases__cls.__bases__
猜你喜欢
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多