Eu tenho uma classe que contém apenas campos e nenhum método, como este:
class Request(object):
def __init__(self, environ):
self.environ = environ
self.request_method = environ.get('REQUEST_METHOD', None)
self.url_scheme = environ.get('wsgi.url_scheme', None)
self.request_uri = wsgiref.util.request_uri(environ)
self.path = environ.get('PATH_INFO', None)
# ...
Isso poderia ser facilmente traduzido para um dict. A classe é mais flexível para adições futuras e pode ser mais rápida __slots__
. Então, haveria uma vantagem em usar um dicionário em vez disso? Um dict seria mais rápido do que uma aula? E mais rápido do que uma classe com slots?
python
oop
class
dictionary
deamon
fonte
fonte
dict
pode fazer sentido, para. grande vantagem: ao depurar, basta dizerprint(request)
e você verá prontamente todas as informações de estado. com a abordagem mais clássica, você terá que escrever seus__str__
métodos personalizados , o que é uma droga se você tiver que fazer isso o tempo todo.Respostas:
Por que você faria este dicionário? Qual é a vantagem? O que acontece se você quiser adicionar algum código posteriormente? Para onde iria seu
__init__
código?As aulas são para agrupar dados relacionados (e geralmente código).
Os dicionários são para armazenar relacionamentos de valor-chave, onde geralmente as chaves são todas do mesmo tipo e todos os valores também são de um tipo. Ocasionalmente, eles podem ser úteis para agrupar dados quando os nomes de chave / atributo não são todos conhecidos antecipadamente, mas geralmente isso é um sinal de que algo está errado com seu projeto.
Mantenha esta uma aula.
fonte
__init__
método da classe . Mas você está certo: eu separaria as coisas que pertencem uma à outra.where would your __init__ code go?
é preocupante. Isso poderia persuadir um desenvolvedor menos experiente de que apenas as classes devem ser usadas, uma vez que um método init não é usado em um dicionário. Absurdo.Use um dicionário, a menos que você precise do mecanismo extra de uma classe. Você também pode usar um
namedtuple
para uma abordagem híbrida:As diferenças de desempenho aqui serão mínimas, embora eu ficaria surpreso se o dicionário não fosse mais rápido.
fonte
Uma classe em python é um dict por baixo. Você obtém alguma sobrecarga com o comportamento da classe, mas não será capaz de notá-lo sem um criador de perfil. Nesse caso, acredito que você se beneficia com a aula porque:
fonte
Eu acho que o uso de cada um é muito subjetivo para eu entrar nisso, então vou me limitar aos números.
Eu comparei o tempo que leva para criar e alterar uma variável em um dicionário, uma classe new_style e uma classe new_style com slots.
Aqui está o código que usei para testá-lo (é um pouco confuso, mas faz o trabalho).
E aqui está a saída ...
Criando ...
Alterando uma variável ...
Então, se você está apenas armazenando variáveis, você precisa de velocidade e não vai exigir que você faça muitos cálculos, eu recomendo usar um dicionário (você pode apenas fazer uma função que se pareça com um método). Mas, se você realmente precisa de classes, lembre-se - sempre use __ slots __ .
Nota:
Testei a 'Classe' com as classes new_style e old_style. Acontece que as classes old_style são mais rápidas de criar, mas mais lentas de modificar (não muito, mas significativo se você estiver criando muitas classes em um loop fechado (dica: você está fazendo isso errado)).
Além disso, os tempos para criar e alterar variáveis podem ser diferentes no seu computador, pois o meu é antigo e lento. Certifique-se de testar você mesmo para ver os resultados 'reais'.
Editar:
Posteriormente, testei o namedtuple: não posso modificá-lo, mas para criar os 10.000 exemplos (ou algo parecido) demorou 1,4 segundos, então o dicionário é realmente o mais rápido.
Se eu alterar a função dict para incluir as chaves e valores e retornar o dict em vez da variável que contém o dict quando eu crio, isso me dá 0,65 em vez de 0,8 segundos.
Criar é como uma classe com slots e alterar a variável é o mais lento (0,17 segundos), portanto , não use essas classes . vá para um dict (velocidade) ou para a classe derivada do objeto ('doce de sintaxe')
fonte
dict
(sem métodos substituídos, acho?). Ele tem o mesmo desempenho de uma classe de novo estilo que foi escrita do zero?Eu concordo com @adw. Eu nunca representaria um "objeto" (no sentido OO) com um dicionário. Os dicionários agregam pares de nome / valor. As classes representam objetos. Eu vi um código onde os objetos são representados com dicionários e não está claro qual é a forma real da coisa. O que acontece quando certos nomes / valores não estão lá? O que restringe o cliente de colocar qualquer coisa dentro. Ou de tentar retirar qualquer coisa. A forma da coisa sempre deve ser claramente definida.
Ao usar Python, é importante construir com disciplina, pois a linguagem permite que o autor dê um tiro no próprio pé de várias maneiras.
fonte
Eu recomendaria uma aula, pois são todos os tipos de informações envolvidas em uma solicitação. Se alguém usasse um dicionário, esperaria que os dados armazenados fossem muito mais semelhantes em natureza. Uma orientação que eu mesmo tendo a seguir é que, se quiser fazer um loop por todo o conjunto de pares chave-> valor e fazer algo, uso um dicionário. Caso contrário, os dados aparentemente têm muito mais estrutura do que um mapeamento básico de chave-> valor, o que significa que uma classe provavelmente seria uma alternativa melhor.
Portanto, fique com a classe.
fonte
Se tudo o que você deseja alcançar é um doce de sintaxe em
obj.bla = 5
vez deobj['bla'] = 5
, especialmente se tiver que repetir muito isso, talvez queira usar alguma classe de contêiner simples como na sugestão de martineaus. No entanto, o código lá é bastante inchado e desnecessariamente lento. Você pode mantê-lo simples assim:Outro motivo para mudar para
namedtuple
s ou uma classe__slots__
pode ser o uso de memória. Os dictos exigem muito mais memória do que os tipos de lista, portanto, esse pode ser um ponto a se pensar.De qualquer forma, no seu caso específico, não parece haver nenhuma motivação para abandonar sua implementação atual. Você não parece manter milhões desses objetos, portanto, nenhum tipo derivado de lista é necessário. E, na verdade, contém alguma lógica funcional dentro do
__init__
, então você também não deve continuarAttrDict
.fonte
types.SimpleNamespace
(disponível desde Python 3.3) é uma alternativa ao AttrDict customizado.Pode ser possível ter seu bolo e comê-lo também. Em outras palavras, você pode criar algo que forneça a funcionalidade de uma classe e de uma instância de dicionário. Veja a receita Dɪᴄᴛɪᴏɴᴀʀʏ ᴡɪᴛʜ ᴀᴛᴛʀɪʙᴜᴛᴇ-sᴛʏʟᴇ ᴀᴄᴄᴇss do ActiveState e comentários sobre as maneiras de fazer isso.
Se você decidir usar uma classe regular em vez de uma subclasse, descobri que a receita Tʜᴇ sɪᴍᴘʟᴇ ʙᴜᴛ ʜᴀɴᴅʏ "ᴄᴏʟʟᴇᴄᴛᴏʀ ᴏғ ᴀ ʙᴜɴᴄʜ ᴏғ ɴᴀᴍᴇᴅ sᴛᴜғғ" ᴄʟᴀss (de Alex Martelli) é muito flexível e útil para o tipo de coisa que parece que você está fazendo (ou seja, criar um agregador de informações relativamente simples). Por ser uma classe, você pode facilmente estender sua funcionalidade ainda mais adicionando métodos.
Por último, deve-se observar que os nomes dos membros da classe devem ser identificadores legais do Python, mas as chaves de dicionário não - portanto, um dicionário forneceria maior liberdade a esse respeito porque as chaves podem ser qualquer coisa hashble (mesmo algo que não seja uma string).
Atualizar
Uma classe
object
(que não tem uma__dict__
) subclasse chamadaSimpleNamespace
(que tem uma) foi adicionada aotypes
módulo Python 3.3 e é mais uma alternativa.fonte
Eu recomendo uma aula. Se você usar uma classe, poderá obter uma dica de tipo conforme mostrado. E a classe oferece suporte à conclusão automática quando a classe é um argumento de função.
fonte