É considerado Pythonic ter várias classes definidas no mesmo arquivo?

31

Ao trabalhar com python pela primeira vez, descobri que acabei escrevendo várias classes no mesmo arquivo, o que se opõe a outras linguagens como Java, que usa um arquivo por classe.

Geralmente, essas classes são compostas de uma classe base abstrata, com 1-2 implementações concretas cujo uso varia um pouco. Publiquei um desses arquivos abaixo:

class Logger(object):

    def __init__(self, path, fileName):
        self.logFile = open(path + '/' + filename, 'w+')
        self.logFile.seek(0, 2)

    def log(self, stringtoLog):
        self.logFile.write(stringToLog)

    def __del__(self):
        self.logFile.close()

class TestLogger(Logger):   

    def __init__(self, serialNumber):
        Logger.__init__('/tests/ModuleName', serialNumber):

    def readStatusLine(self):
        self.logFile.seek(0,0)
        statusLine = self.logFile.readLine()
        self.logFile.seek(0,2)
        return StatusLine

    def modifyStatusLine(self, newStatusLine):
        self.logFile.seek(0,0)
        self.logFile.write(newStatusLine)
        self.logFile.seek(0,2)

class GenericLogger(Logger):

    def __init__(self, fileName):
        Logger.__init__('/tests/GPIO', fileName):

    def logGPIOError(self, errorCode):
        self.logFile.write(str(errorCode))

Como visto acima, eu tenho uma classe base do Logger, com algumas diferenças de implementação abaixo disso.

A pergunta: esse padrão é para python ou para qualquer idioma? Quais problemas podem surgir ao usar esta implementação, se houver?

Edição: Eu realmente não estou procurando orientação sobre esse arquivo específico , mas em um sentido mais geral. E se as aulas acabassem sendo 3-5 métodos moderadamente complexos? Faria sentido separá-los então? Onde está o ponto de corte para dizer que você deve dividir um arquivo?

Ampt
fonte
3
Limitar a uma classe por arquivo NÃO é uma coisa do C ++. Java é a única linguagem que conheço onde é considerada algo a ser evitado. No C ++, é extremamente comum que um único arquivo .h / .cpp tenha uma classe principal e muitas classes auxiliares, que podem ou não ser privadas para a classe principal.
Gort the Robot
@StevenBurnap Eu removi o c ++ como exemplo, como você está correto.
Ampt 30/08/2013
11
Também é feito em php para facilitar o carregamento automático. Por outro lado, no php, você pode declarar explicitamente o namespace.
bodo

Respostas:

24

Está bem. Também é bom em C ++, para referência.

Manter coisas bem unidas é uma prática sensata. Evitar o acoplamento inadequado também é uma boa prática. Encontrar o equilíbrio certo não é uma questão de regras estritas, mas sim de encontrar um equilíbrio entre diferentes preocupações.

Algumas regras práticas:

  1. Tamanho

    Arquivos excessivamente grandes podem ser feios, mas esse não é o caso aqui. A feiúra é provavelmente uma razão suficientemente boa para dividir um arquivo, mas desenvolver esse senso estético é em grande parte uma questão de experiência, por isso não ajuda a descobrir o que fazer a priori

  2. Separação de preocupações

    Se suas implementações concretas têm preocupações internas muito diferentes, seu arquivo único acumula todas essas preocupações. Por exemplo, implementações com dependências sem sobreposição fazem com que seu único arquivo dependa da união de todas essas dependências.

    Portanto, às vezes pode ser razoável considerar que o acoplamento das subclasses às dependências supera o acoplamento à interface (ou, inversamente, a preocupação de implementar uma interface é mais fraca do que as preocupações internas a essa implementação).

    Como um exemplo específico, use uma interface de banco de dados genérica. Implementações concretas usando um banco de dados na memória, um SQL RDBMS e uma consulta na Web, respectivamente, podem não ter nada em comum além da interface, e forçar todos os que desejam que a versão leve na memória também importe uma biblioteca SQL é desagradável.

  3. Encapsulamento

    Embora você possa escrever classes bem encapsuladas no mesmo módulo, isso poderia incentivar o acoplamento desnecessário apenas porque você tem acesso aos detalhes da implementação que, de outra forma, não seriam exportados para fora do módulo.

    Acho que esse é um estilo pobre, mas você poderia aplicar uma melhor disciplina dividindo o módulo se realmente não conseguir quebrar o hábito.

Sem utilidade
fonte
2
Sua resposta seria mais forte se citasse referências externas demonstrando a normalidade da combinação de classes em um arquivo ou fornecendo mais explicações indicando por que está tudo bem.
11
Editei a pergunta para salientar que este é simplesmente um exemplo do que quero dizer e não representa exatamente a natureza da pergunta. Por que mantê-los no mesmo arquivo é melhor do que simplesmente importá-los quando necessário?
Ampt 30/08/13
Ter muitos arquivos pequenos pode ser tão difícil de gerenciar quanto ter alguns arquivos gigantes. Python é uma linguagem bastante concisa. Seu exemplo mostra isso. Essas três classes estão diretamente relacionadas e provavelmente cabem em uma única janela do editor sem rolar.
Gort the Robot
11
@ GlenH7 - Não tenho certeza sobre as referências, uma vez que elas simplesmente mudam de mim para fazer uma reivindicação diretamente, para mim alegando que meu viés de seleção é válido. Tentei me concentrar na explicação.
Inútil
7

Meus documentos de referência habituais para saber o que é pitônico.

Simples é melhor que complexo.

Flat é melhor que aninhado.

Do Zen Of Python

Quase sem exceção, os nomes das classes usam a convenção CapWords.

Nomes de pacotes e módulos Os módulos devem ter nomes curtos e todos em minúsculas. [...] Os nomes dos módulos são mapeados para nomes de arquivos

Do PEP 8

Minha interpretação é que está tudo bem, pois isso manteria as coisas simples e simples. Além disso, como os nomes de classes e arquivos têm casos diferentes, eles não devem ser idênticos de qualquer maneira, então eu não veria nenhum problema ao compactar várias classes relacionadas em um arquivo.

SylvainD
fonte
7
Você poderia reduzir isso às partes relevantes para a pergunta? Eu li as duas vezes várias vezes, mas estou tendo dificuldades para escolher quais partes, em particular, estão relacionadas à minha pergunta atual.
Ampt
11
Na verdade, eu editei minha resposta.
precisa saber é o seguinte
1

O que você tem agora está bem. Vá e navegue na biblioteca padrão - há muitos módulos com várias classes relacionadas em um único arquivo. Em algum momento, as coisas ficam maiores e, eventualmente, você deseja começar a usar módulos com vários arquivos, mas não há regras reais sobre quando. As coisas ficam divididas quando um arquivo começa a parecer "muito grande".

Sean McSomething
fonte
0

Definitivamente, está tudo bem e eu encorajo você a ter várias classes em um arquivo, desde que sejam realizadas. Em geral, suas aulas devem ser curtas e concisas, e você deve dividir o comportamento em duas ou mais classes do que criar monolíticas enormes. Ao escrever várias turmas pequenas, é realmente necessário e útil manter as que estão relacionadas no mesmo arquivo.

wirrbel
fonte
-1

Em suma - inferno sim.

Além disso, ter várias classes em um único arquivo às vezes é muito útil. Alguns pacotes ( six, bottle) são enviados explicitamente em um único arquivo para serem facilmente integrados a qualquer módulo de terceiros sem a instalação do pip (às vezes desejável). Mas, certifique-se de organizar bem seu código. Use intensivamente comentários de código e blocos de separação para torná-lo mais legível.

Artur Barseghyan
fonte
3
este não parece acrescentar nada substancial sobre resposta antes publicado alguns anos atrás
mosquito