Existe algum motivo para uma declaração de classe herdar object
?
Acabei de encontrar um código que faz isso e não consigo encontrar uma boa razão para isso.
class MyClass(object):
# class code follows...
Existe algum motivo para uma declaração de classe herdar object
?
Acabei de encontrar um código que faz isso e não consigo encontrar uma boa razão para isso.
class MyClass(object):
# class code follows...
Respostas:
Existe algum motivo para uma declaração de classe herdar
object
?
No Python 3, além da compatibilidade entre o Python 2 e 3, não há razão . No Python 2, muitos motivos .
No Python 2.x (a partir do 2.2), existem dois estilos de classes, dependendo da presença ou ausência de object
uma classe base:
classes de estilo "clássico" : elas não têm object
como classe base:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
classes de estilo "novas" : elas têm, direta ou indiretamente (por exemplo, herança de um tipo interno ), object
como classe base:
>>> class NewSpam(object): # directly inherit from object
... pass
>>> NewSpam.__bases__
(<type 'object'>,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(<type 'int'>,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object
(<type 'object'>,)
Sem dúvida, ao escrever uma aula, você sempre desejará aulas de novo estilo. As vantagens de fazer isso são inúmeras, para listar algumas delas:
Suporte para descritores . Especificamente, as seguintes construções são possíveis com descritores:
classmethod
: Um método que recebe a classe como um argumento implícito em vez da instância.staticmethod
: Um método que não recebe o argumento implícito self
como primeiro argumento.property
: Crie funções para gerenciar a obtenção, configuração e exclusão de um atributo.__slots__
: Economiza o consumo de memória de uma classe e também resulta em acesso mais rápido aos atributos. Obviamente, impõe limitações .O __new__
método estático: permite personalizar como novas instâncias de classe são criadas.
Ordem de resolução de método (MRO) : em que ordem as classes base de uma classe serão pesquisadas ao tentar resolver qual método chamar.
Relacionado a MRO, super
chamadas . Veja também, super()
considerado super.
Se você não herdar object
, esqueça-os. Uma descrição mais exaustiva dos pontos anteriores, além de outras vantagens de "novas" classes de estilo, pode ser encontrada aqui .
Uma das desvantagens das novas classes de estilo é que a própria classe exige mais memória. A menos que você esteja criando muitos objetos de classe, duvido que isso seja um problema e seja um afundamento negativo em um mar de aspectos positivos.
No Python 3, as coisas são simplificadas. Existem apenas classes de novo estilo (chamadas de classes), portanto, a única diferença na adição object
é exigir que você digite mais 8 caracteres. Este:
class ClassicSpam:
pass
é completamente equivalente (além do nome :-) a isso:
class NewSpam(object):
pass
e para isso:
class Spam():
pass
Todos têm object
em seus __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
No Python 2: sempre herda object
explicitamente . Receba as vantagens.
No Python 3: herdar object
se você estiver escrevendo um código que tenta ser independente do Python, ou seja, ele precisa funcionar tanto no Python 2 quanto no Python 3. Caso contrário, não faz realmente nenhuma diferença, já que o Python o insere para você Por trás das cenas.
object
. No IIRC, houve um momento em que nem todos os tipos internos ainda eram portados para classes de novo estilo.
object
. Eu tenho um Python 2.2.3 por perto e, após uma verificação rápida, não consegui encontrar um infrator, mas reformularei a resposta mais tarde para torná-la mais clara. Estaria interessado se você pudesse encontrar um exemplo, porém, minha curiosidade é despertada.
object
em suas bases.
staticmethod
e classmethod
funciona bem mesmo em aulas de estilo antigo. property
sorta funciona para leitura em classes de estilo antigo, mas falha em interceptar gravações (portanto, se você atribuir ao nome, a instância ganha um atributo do nome dado que oculta a propriedade). Observe também que __slots__
o aprimoramento na velocidade de acesso aos atributos se refere principalmente a desfazer a perda sofrida pelo acesso a atributos de classe de novo estilo, portanto, não é realmente um ponto de venda de classes de novo estilo (a economia de memória é um ponto de venda).
Python 3
class MyClass(object):
= Classe de novo estiloclass MyClass:
= Classe de novo estilo (herda implicitamente de object
)Python 2
class MyClass(object):
= Classe de novo estiloclass MyClass:
= CLASSE DE ESTILO ANTIGOExplicação :
Ao definir classes base no Python 3.x, você pode remover o object
da definição. No entanto, isso pode abrir a porta para um problema seriamente difícil de rastrear ...
O Python introduziu novas classes de estilo no Python 2.2, e agora as classes antigas são realmente muito antigas. A discussão de classes de estilo antigo está oculta nos documentos 2.x e inexistente nos documentos 3.x.
O problema é, a sintaxe para as classes de estilo antigo em Python 2.x é o mesmo que a sintaxe alternativa para as classes de estilo novo em Python 3.x . O Python 2.x ainda é muito utilizado (por exemplo, GAE, Web2Py), e qualquer código (ou codificador) involuntariamente trazendo definições de classe no estilo 3.x para o código 2.x vai acabar com alguns objetos básicos seriamente desatualizados. E como as aulas de estilo antigo não estão no radar de ninguém, elas provavelmente não saberão o que as atingiu.
Então, basta soletrar o caminho longo e poupar alguns desenvolvedores do 2.x as lágrimas.
__metaclass__ = type
na parte superior do módulo (após a from __future__ import absolute_import, division, print_function
linha :-)); é um hack de compatibilidade no Py2 que torna todas as classes subsequentemente definidas no módulo novo estilo por padrão, e no Py3 é completamente ignorado (apenas uma variável global aleatória), por isso é inofensivo.
Sim, este é um objeto de 'novo estilo'. Foi um recurso introduzido no python2.2.
Os novos objetos de estilo têm um modelo de objeto diferente dos objetos clássicos e algumas coisas não funcionarão corretamente com objetos de estilo antigo, por exemplo super()
, @property
e descritores. Consulte este artigo para obter uma boa descrição do que é uma nova classe de estilo.
Link SO para obter uma descrição das diferenças: Qual é a diferença entre o estilo antigo e as novas classes de estilo no Python?
object
Python 2. #
História do Learn Python da maneira mais difícil :
A versão original de Python de uma classe foi quebrada de várias maneiras sérias. No momento em que essa falha foi reconhecida, já era tarde demais e eles precisavam apoiá-la. Para resolver o problema, eles precisavam de um estilo de "nova classe" para que as "classes antigas" continuassem funcionando, mas você pode usar a nova versão mais correta.
Eles decidiram que usariam a palavra "objeto", em minúsculas, para ser a "classe" da qual você herda para criar uma classe. É confuso, mas uma classe é herdada da classe chamada "objeto" para criar uma classe, mas não é realmente um objeto, é uma classe, mas não esqueça de herdar do objeto.
Também para que você saiba qual é a diferença entre as classes de novo estilo e as de estilo antigo, é que as classes de novo estilo sempre herdam da object
classe ou de outra classe que herdou de object
:
class NewStyle(object):
pass
Outro exemplo é:
class AnotherExampleOfNewStyle(NewStyle):
pass
Enquanto uma classe base de estilo antigo se parece com isso:
class OldStyle():
pass
E uma classe infantil à moda antiga é assim:
class OldStyleSubclass(OldStyle):
pass
Você pode ver que uma classe base Old Style não herda de nenhuma outra classe; no entanto, é claro que as classes Old Style podem herdar uma da outra. Herdar do objeto garante que determinadas funcionalidades estejam disponíveis em todas as classes do Python. Novas classes de estilo foram introduzidas no Python 2.2
object
não é tão confuso e, na verdade, é bastante padrão. O Smalltalk possui uma classe raiz denominada Object
e uma metaclasse raiz denominada Class
. Por quê? Porque, assim como Dog
é uma classe para cães, Object
é uma classe para objetos e Class
é uma classe para classes. Java, C #, ObjC, Ruby e a maioria das outras linguagens OO baseadas em classe que as pessoas usam hoje que têm uma classe raiz usam alguma variação Object
como o nome, não apenas Python.
Sim, é histórico . Sem ele, ele cria uma classe de estilo antigo.
Se você usa type()
em um objeto de estilo antigo, apenas obtém "instância". Em um objeto de novo estilo, você obtém sua classe.
type()
uma classe de estilo antigo, obtém "classobj" em vez de "type".
A sintaxe da instrução de criação de classe:
class <ClassName>(superclass):
#code follows
Na ausência de outras superclasses das quais você deseja herdar especificamente, superclass
deve sempre ser object
, que é a raiz de todas as classes no Python.
object
é tecnicamente a raiz das classes de "novo estilo" no Python. Mas as novas classes de estilo hoje são tão boas quanto o único estilo de classe.
Mas, se você não usar explicitamente a palavra object
ao criar classes, como os outros mencionaram, o Python 3.x herda implicitamente da object
superclasse. Mas acho que explícito é sempre melhor que implícito (inferno)