2016-01-20 4 views
0
class SingletonLoader(object): 
    cachedStates = {} 

    def __new__(cls, key, loadFunc): 
     print "SingletonLoader.new: cls = %s, key = %s, loadFunc = %s" % (cls, key, loadFunc) 

     if key not in cls.cachedStates: 
      plugin.msg("New key %s, invoking loader function %s" % (key, loadFunc)) 
      cls.cachedStates[key] = loadFunc() 
      plugin.msg("Cached %s under key %s" % (key, cls.cachedStates[key])) 

     return super(SingletonLoader, cls).__new__(cls, key, loadFunc) 


    def __init__(self, key, loadFunc): 
     # Set members from the cached state matching the key. 
     self.__dict__ = self.__class__.cachedStates[key] 

Обратная линия супер (SingletonLoad ...... бросает ошибку, упомянутую в названии.объект .__ новый __() не принимает parametrs

Любая идея, почему.

+1

Вы можете найти это полезным: http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init –

ответ

1

super не . вставная замена статический определенных суперкласс класса есть два вопрос:

  1. Если object.__new__ действительно следующий метод в MRO, то вы не можете пройти дополнительную argume nts, ​​так как object.__new__ не принимает их.

  2. Если какой-либо другой класс C находится рядом в MRO, и C.__new__ли ожидать дополнительные аргументы, то вы должны поставить их.

Битва-22, не так ли? Решение состоит в том, что вы должны рассмотреть иерархию классов в целом при использовании super, тем более, если вы используете метод, который может быть выполнен object. В этом случае вы должны убедиться в том, что существует базовый класс, который может принимать дополнительные аргументы для __new__, и будет иметь object следующий класс в своем MRO, чтобы он мог вызывать __new__ без дополнительных аргументов.

Если вы используете super, чтобы избежать записи object.__new__(cls), значит, вы используете super.

+1

'object' следующий в строке,' SingletonLoader.mro() -> [ __main __. SingletonLoader, object] '. Делегирование «type», которое действительно знает, как создавать * новые * вещи, обычно происходит так, что я не уверен, что OP пытается выполнить здесь. –

+0

'object' следующий в строке в * этом * случае, что означает, что правильный вызов -' super (SingletonLoader, cls) .__ new __ (cls) '. Но в целом «супер» предназначен для совместного наследования, а это значит, что вам нужно рассмотреть * любой * класс, который может вызвать метод. Нет никакой гарантии, что 'super' будет ссылаться на' object', поскольку у потомка 'SingletonLoader' может быть другой MRO. – chepner

+0

Если вы пытались дать общий ответ, я согласен и нехорошо; мой комментарий был локализован для конкретного сценария, предоставленного OP. –

Смежные вопросы