A resposta a esta pergunta (embora simples) é bastante difícil de encontrar. Pesquisando coisas como "classe base de objetos python" ou similar, aparece páginas e páginas de tutoriais sobre programação orientada a objetos. Upvoting porque este é o primeiro elo que me levou aos termos de pesquisa "python vs. novo estilo old objetos"
vastlysuperiorman
Respostas:
765
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 .
História do Python 2.x:
No Python 2.x (a partir do 2.2), existem dois estilos de classes, dependendo da presença ou ausência de objectuma classe base:
classes de estilo "clássico" : elas não têm objectcomo classe base:
>>>classClassicSpam:# no base class...pass>>>ClassicSpam.__bases__()
classes de estilo "novas" : elas têm, direta ou indiretamente (por exemplo, herança de um tipo interno ), objectcomo classe base:
>>>classNewSpam(object):# directly inherit from object...pass>>>NewSpam.__bases__(<type 'object'>,)>>>classIntSpam(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 selfcomo primeiro argumento.
propriedades com 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.
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.
História do Python 3.x:
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:
classClassicSpam:pass
é completamente equivalente (além do nome :-) a isso:
classNewSpam(object):pass
e para isso:
classSpam():pass
Todos têm objectem seus __bases__.
>>>[object in cls.__bases__ for cls in{Spam,NewSpam,ClassicSpam}][True,True,True]
Então o que você deveria fazer?
No Python 2: sempre herda objectexplicitamente . Receba as vantagens.
No Python 3: herdar objectse 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.
"dependendo da presença ou ausência de um tipo embutido como classe base" => na verdade, não se trata de "ausência ou presença de um tipo embutido como classe base", mas se a classe herda - direta ou indiretamente - object. No IIRC, houve um momento em que nem todos os tipos internos ainda eram portados para classes de novo estilo.
bruno desthuilliers 19/03/19
@brunodesthuilliers Minha impressão foi de que todos os tipos internos herdaram 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.
Dimitris Fasarakis Hilliard
Com toda a honestidade (consulte o "IIRC" no meu comentário anterior), não tenho 101% de certeza sobre esse ponto (se todos os tipos internos já foram convertidos em classes de novo estilo quando foram introduzidas) - talvez seja claro errado, ou isso pode ter afetado apenas alguns dos tipos de lib padrão (mas não embutidos). Mas, no entanto, acho que deveria ser melhor esclarecer que o que faz uma classe de novo estilo está tendo objectem suas bases.
Bruno desthuilliers
7
stackoverflow muito ruim apenas upvote = upvote + 1 para essas respostas, gostaria de fazer upvote + = N
PirateApp
1
staticmethode classmethodfunciona bem mesmo em aulas de estilo antigo. propertysorta 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).
ShadowRanger
540
Python 3
class MyClass(object): = Classe de novo estilo
class MyClass:= Classe de novo estilo (herda implicitamente de object)
Python 2
class MyClass(object): = Classe de novo estilo
class MyClass:= CLASSE DE ESTILO ANTIGO
Explicação :
Ao definir classes base no Python 3.x, você pode remover o objectda 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.
"Ao definir classes base no Python 3.x, você pode remover o objeto da definição. No entanto, isso pode abrir a porta para um problema seriamente difícil de rastrear ..." A quais problemas você está se referindo?
Aidis
6
@Aidis: Eu acho que eles querem dizer que o código executado tanto no Py2 quanto no Py3 seria bom no Py3, mas seria quebrado no Py2 se depender de recursos de classe de novo estilo. Pessoalmente, se estou escrevendo um código como esse, omito a herança explícita e apenas coloco __metaclass__ = typena parte superior do módulo (após a from __future__ import absolute_import, division, print_functionlinha :-)); é 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.
ShadowRanger
400
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(), @propertye descritores. Consulte este artigo para obter uma boa descrição do que é uma nova classe de estilo.
+1 Isto. Observe que as classes de estilo antigo desapareceram no Python 3, então você só precisa herdar do objectPython 2. #
9
Esta não é uma resposta real. apenas menciona outros artigos. Penso que a resposta de Yarin deve ser aceita como resposta a esta pergunta.
Alwbtc 01/01
2
@alwbtc: Esta resposta também tem algo novo. Por exemplo, a menção de "super ()" me levou a outra importante [aqui] ( stackoverflow.com/questions/576169/… ).
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 objectclasse ou de outra classe que herdou de object:
classNewStyle(object):pass
Outro exemplo é:
classAnotherExampleOfNewStyle(NewStyle):pass
Enquanto uma classe base de estilo antigo se parece com isso:
classOldStyle():pass
E uma classe infantil à moda antiga é assim:
classOldStyleSubclass(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
Chamar a classe raiz objectnão é tão confuso e, na verdade, é bastante padrão. O Smalltalk possui uma classe raiz denominada Objecte 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 Objectcomo o nome, não apenas Python.
Abarnert
30
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.
Além disso, se você usa type()uma classe de estilo antigo, obtém "classobj" em vez de "type".
Joel Sjögren
7
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, superclassdeve 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 objectao criar classes, como os outros mencionaram, o Python 3.x herda implicitamente da objectsuperclasse. Mas acho que explícito é sempre melhor que implícito (inferno)
Respostas:
No Python 3, além da compatibilidade entre o Python 2 e 3, não há razão . No Python 2, muitos motivos .
História do Python 2.x:
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:classes de estilo "novas" : elas têm, direta ou indiretamente (por exemplo, herança de um tipo interno ),
object
como classe base: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ícitoself
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.
História do Python 3.x:
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:é completamente equivalente (além do nome :-) a isso:
e para isso:
Todos têm
object
em seus__bases__
.Então o que você deveria fazer?
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.fonte
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
eclassmethod
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 deobject
)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.
fonte
__metaclass__ = type
na parte superior do módulo (após afrom __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?
fonte
object
Python 2. #História do Learn Python da maneira mais difícil :
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 deobject
:Outro exemplo é:
Enquanto uma classe base de estilo antigo se parece com isso:
E uma classe infantil à moda antiga é assim:
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
fonte
object
não é tão confuso e, na verdade, é bastante padrão. O Smalltalk possui uma classe raiz denominadaObject
e uma metaclasse raiz denominadaClass
. Por quê? Porque, assim comoDog
é uma classe para cães,Object
é uma classe para objetos eClass
é 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çãoObject
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.fonte
type()
uma classe de estilo antigo, obtém "classobj" em vez de "type".A sintaxe da instrução de criação de classe:
Na ausência de outras superclasses das quais você deseja herdar especificamente,
superclass
deve sempre serobject
, 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 daobject
superclasse. Mas acho que explícito é sempre melhor que implícito (inferno)Referência
fonte