Нужно ли или полезно ли наследовать от объекта python в Python 3.x?

94

В более старой версии python, когда вы создаете класс в python, он может наследовать от объекта, который, насколько я понимаю, специальный встроенный элемент python, который позволяет вашему объекту быть объектом нового стиля.

А как насчет более новой версии (> 3.0 и 2.6)? Я погуглил об объекте класса, но получил так много результатов (по очевидным причинам). Намек?

Спасибо!

Томас
источник
2
Если ваш код также будет использоваться в версии 2.x, лучше указать явно.
smci
1
В этом вопросе есть хороший ответ: stackoverflow.com/questions/4015417/…
nngeek

Ответы:

94

Вам не нужно наследовать от, objectчтобы иметь новый стиль в python 3. Все классы имеют новый стиль.

Тихий призрак
источник
5
Обратите внимание, что это означает, что все классы наследуются objectнезависимо от того, вводится ли явный (object)или нет в Python 3.1
u0b34a0f6ae
8
В этом нет необходимости, но в разделе «Перенос кода Python на Python 3» указано, что он все еще действителен: docs.python.org/py3k/howto/pyporting.html#subclass-object Также: docs.python.org/reference/ …
гиперборианский
Из этого сообщения, упомянутого в комментарии nngeek, похоже, что хорошая стабильная ссылка для старого стиля и нового стиля (действительно актуальна только для Py2): docs.python.org/2/reference/… - похоже, что приведенные выше ссылки с тех пор изменилось.
Эрик Кузино,
80

Я понимаю, что это старый вопрос, но стоит отметить, что даже в python 3 эти две вещи не совсем одно и то же.

Если вы явно наследуете от object, то, что вы на самом деле делаете, наследует от, builtins.object независимо от того, на что это указывает в данный момент.

Поэтому у меня мог быть какой-то (очень дурацкий) модуль, который по какой-то причине переопределяет объект. Назовем этот первый модуль newobj.py:

import builtins

old_object = builtins.object  # otherwise cyclic dependencies

class new_object(old_object):

    def __init__(self, *args, **kwargs):
        super(new_object, self).__init__(*args, **kwargs)
        self.greeting = "Hello World!" 

builtins.object = new_object  #overrides the default object

Затем в другом файле ("klasses.py"):

class Greeter(object):
    pass

class NonGreeter:
    pass

Затем в третьем файле (который мы действительно можем запустить):

import newobj, klasses  # This order matters!

greeter = klasses.Greeter()
print(greeter.greeting)  # prints the greeting in the new __init__

non_greeter = klasses.NonGreeter()
print(non_greeter.greeting) # throws an attribute error

Итак, вы можете видеть, что в случае, когда он явно наследуется от объекта, мы получаем другое поведение, чем там, где вы разрешаете неявное наследование.

Филип Адлер
источник
14
Это актуально, потому что в целом ожидается, что поведение эквивалентно. Это не эквивалент, отсюда и мои наблюдения.
Филип Адлер,