tuplas divisão em Python - melhores práticas?

votos
12

Eu tenho um método no meu código Python que retorna uma tupla - uma linha de uma consulta SQL. Vamos dizer que tem três campos: (jobId, etiqueta, nome de usuário)

Para facilitar a passá-la em torno de entre as funções, eu estive passando toda a tupla como uma variável chamada 'trabalho'. Eventualmente, no entanto, quero chegar aos pedaços, então eu tenho usado um código como este: (jobId, etiqueta, username) = trabalho

Eu percebi, no entanto, que este é um pesadelo de manutenção, porque agora eu nunca pode adicionar novos campos para o conjunto de resultados sem quebrar todo o meu código existente. Como eu deveria ter escrito isso?

Aqui estão as minhas duas melhores suposições: (jobId, etiqueta, username) = (trabalho [0], trabalho [1], trabalho [2]) ... mas isso não escala bem quando você tem 15 ... 20 campos

ou para converter os resultados da consulta SQL para um dicionário de imediato e passar essa volta (eu não tenho controle sobre o fato de que ele começa a vida como uma tupla, que é fixo para mim)

Publicado 03/09/2008 em 14:48
fonte usuário
Em outras línguas...                            


9 respostas

votos
13

@Staale

Há um caminho melhor:

job = dict(zip(keys, values))
Respondeu 03/09/2008 em 15:51
fonte usuário

votos
13

Eu diria que um dicionário é definitivamente a melhor maneira de fazê-lo. É facilmente extensível, permite dar a cada valor de um nome sensato, e Python tem um monte de recursos de linguagem embutidos para o uso e manipulação de dicionários. Se você precisa adicionar mais campos mais tarde, tudo que você precisa mudar é o código que converte a tupla a um dicionário e o código que realmente faz uso dos novos valores.

Por exemplo:

job={}
job['jobid'], job['label'], job['username']=<querycode>
Respondeu 03/09/2008 em 14:50
fonte usuário

votos
5

Esta é uma questão de idade, mas ...

Eu sugiro usar uma tupla nomeado nesta situação: collections.namedtuple

Esta é a parte, em particular, que você gostaria de encontrar útil:

Subclassing não é útil para adicionar, campos armazenados novos. Em vez disso, basta criar um novo tipo tupla chamado a partir do atributo _Fields.

Respondeu 17/07/2009 em 17:08
fonte usuário

votos
3

Talvez este seja um exagero para o seu caso, mas eu seria tentado a criar uma classe de "trabalho" que leva o tuple como seu argumento construtor e tem respectivas propriedades nele. Eu, então, passar instâncias desta classe em torno de vez.

Respondeu 03/09/2008 em 14:57
fonte usuário

votos
2

Uma questão de idade, mas já que ninguém mencionou isso vou acrescentar isso a partir do Python Cookbook:

Receita 81252: Usando dtuple para consulta flexível resultado Acesso

Esta receita é projetado especificamente para lidar com resultados de banco de dados, e a solução dtuple permite que você acesse os resultados por nome ou número de índice. Isso evita ter que acessar tudo pelo índice que é muito difícil de manter, como observou na sua pergunta.

Respondeu 22/12/2008 em 21:22
fonte usuário

votos
2

Gostaria de usar um dicionário. Você pode converter a tupla a um dicionário desta forma:

values = <querycode>
keys = ["jobid", "label", "username"]
job = dict([[keys[i], values [i]] for i in xrange(len(values ))])

Isso vai primeiro criar uma matriz [[ "jobid", val1], [ "rótulo", val2], [ "username", val3]] e, em seguida, convertê-lo em um dicionário. Se a ordem resultado ou contar alterações, você só precisa mudar a lista de chaves para coincidir com o novo resultado.

PS ainda fresco em Python mim mesmo, então pode haver maneiras melhores fora de fazer isso.

Respondeu 03/09/2008 em 14:59
fonte usuário

votos
0

Se você estiver usando o pacote MySQLdb, você pode configurar seus objetos de cursor para retornar dicts em vez de tuplas.

import MySQLdb, MySQLdb.cursors
conn = MySQLdb.connect(..., cursorclass=MySQLdb.cursors.DictCursor)
cur = conn.cursor() # a DictCursor
cur2 = conn.cursor(cursorclass=MySQLdb.cursors.Cursor) # a "normal" tuple cursor
Respondeu 09/04/2010 em 17:28
fonte usuário

votos
0

Com uma tupla será sempre um aborrecimento para adicionar ou alterar campos. Você está certo de que um dicionário será muito melhor.

Se você quiser algo com sintaxe um pouco mais amigável que você pode querer dar uma olhada nas respostas a esta pergunta sobre um simples objeto 'struct-like'. Dessa forma, você pode passar em torno de um objeto, por exemplo job, e acessar seus campos ainda mais facilmente do que uma tupla ou dict:

job.jobId, job.username = jobId, username
Respondeu 03/09/2008 em 14:51
fonte usuário

votos
-2

Que tal agora:

class TypedTuple:
    def __init__(self, fieldlist, items):
       self.fieldlist = fieldlist
       self.items = items
    def __getattr__(self, field):
       return self.items[self.fieldlist.index(field)]

Você poderia, então, fazer:

j = TypedTuple(["jobid", "label", "username"], job)
print j.jobid

Deve ser fácil para trocar self.fieldlist.index(field)com uma pesquisa de dicionário mais tarde ... apenas editar o seu __init__método! Algo como Staale faz.

Respondeu 03/09/2008 em 15:02
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more