如何修复此TypeError丢失“自我”参数

时间:2019-01-30 16:14:05

标签: python oop singleton

在我使用self作为missing 1 required positional argument: 'self'之类的参数的那些方法上获取TypeError。如果该方法具有多个参数,包括self,则将显示类似的错误,即缺少另一个位置参数。

我首先制作了一个单例对象,该对象检查其自身的引用以保持其奇异性。我用__new__来做到这一点。

core.py

import pyglet.window

class Core(object):

    def __new__(cls, *args, **kwargs):
        if not cls:
            cls = object.__new__(cls, *args, **kwargs)
        return cls

    def __init__(self):
        self._instance = None
        self._window = None

    def __repr__(self):
        return '<%s object at %s>' % (Core.__name__, hex(id(Core)))

    def scene(self, width, height):
        self._window = pyglet.window.Window(width=width, height=height)

script.py

from core import Core

c = Core()
print(c.__repr__())
c.scene(640, 480)

错误:

    print(c.__repr__())
TypeError: __repr__() missing 1 required positional argument: 'self'

    c.scene(640, 480)
TypeError: scene() missing 1 required positional argument: 'height'

这种方法不是唯一的情况,所以我想了解发生了什么以及如何解决此问题。 谢谢您的宝贵时间。

编辑:

__repr__没问题。我想要其他方法,例如scene(self, width, height)或可以将self作为一个参数创建的任何方法。第二个错误,显示该代码给其他方法带来的错误

我需要Core类来创建一个单例对象,因此我可以使用其他文件来引用此Core._window东西。我认为经过修改的说明可以澄清我之前想要的内容。抱歉,为了方便。

3 个答案:

答案 0 :(得分:2)

糟糕,__new__接收该类,并应返回新创建的对象!当您的代码返回类本身时,事情就出错了。您应该具有:

class Core(object):

    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls, *args, **kwargs)
        return obj
    ...

总之__new__是高级配置,主要用于无法在__init__中配置的不可变对象。在您的示例中,您应该将其删除:

class Core(object):

    def __init__(self):
        self._instance = None
        self._window = None

    def __repr__(self):
        return '<%s object at %s>' % (Core.__name__, hex(id(Core)))

对于普通对象来说足够了。您确实可以使用__new__来构建单例,甚至可以使用它来构建单例的层次结构,这意味着Core的每个子类都将是一个单例:

class Core(object):
    _obj = None
    def __new__(cls, *args, **kwargs):
        if cls._obj is None or not isinstance(cls._obj, cls):
            cls._obj = object.__new__(cls, *args, **kwargs)
        return cls._obj

    def __init__(self):
        self._instance = None
        self._window = None

    def __repr__(self):
        return '<%s object at %s>' % (Core.__name__, hex(id(self)))

请注意,我的班级__repr__使用id(self)来标识对象而不是班级。

演示:

>>> c = Core()
>>> d = Core()
>>> c is d
True
>>> class Child(Core):
    pass

>>> ch = Child()
>>> ch is c
False
>>> ch2 = Child()
>>> ch2 is ch
True

答案 1 :(得分:0)

正确的方法是像这样使用repr

repr(c)

答案 2 :(得分:0)

您的代码几乎可以正常工作。在这里看看:

class Core(object):

    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self):
        pass

    def __repr__(self):
        return '<%s object at %s>' % (Core.__name__, hex(id(self)))

core = Core()
print(id(core))

core1 = Core()
print(id(core1))

print(repr(core))
print(repr(core1))