Devo armazenar as coordenadas x, y como uma matriz, um objeto de classe ou duas variáveis?

5

Eu tenho um MyObject que tem uma coordenada xey.

até onde eu posso ver, posso armazená-lo de três maneiras:

class MyObject:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class MyObject:
    def __init__(self, x, y):
        self.position = [x, y]

class MyObject:
    def __init__(self, x, y):
        self.position = Coord(x,y) #Coord class created elsewhere

Existe alguma prática recomendada para isso?

Quando estou pensando que isso é relevante, ao passar essas coordenadas para outros métodos:

por exemplo,

myObj = MyObject(0,0)
searchLocation(myObj.x, myObj.y)
searchLocation2(myObj.position)
    
por dwjohnston 05.09.2014 / 03:50
fonte

8 respostas

1

Se você não tiver dados suficientes para decidir, escolha a opção mais flexível. A escolha do objeto permitiria que você tivesse as outras duas opções como propriedades. (Embora eu, como o comentário sugere, escolha uma tupla em uma lista.)

    
por 30.09.2014 / 02:11
fonte
0

Acho que a terceira implementação do MyObject é a melhor, pois separa o objeto da matemática 2D do sistema de coordenadas. (você pode implementar uma biblioteca matemática completa para as coordenadas e é completamente independente dos objetos criados). Agora, a fim de tornar os objetos mais flexíveis, você poderia criar funções que pegassem dois números para xey ou um objeto Coord e estivessem preparados para adicionar mais enquanto seu sistema cresce.

    
por 05.09.2014 / 09:12
fonte
0

Sim, depende de quanto "cidadão de primeira classe" é a posição. Se muitos outros objetos o consumirem ou produzirem e / ou houver um comportamento relacionado a posições que você deseja capturar / impor (como a resposta de Gus), é melhor que você faça a sua própria classe.

Se você fizer optar por torná-la sua própria classe, você deve definitivamente deixar de usar os elementos x e y no construtor para MyObject e, em vez disso, fazer isso um objeto Position. Provavelmente, não há razão para que o MyObject esteja ciente do que um objeto Position precisa ser construído, pelo menos não obviamente no exemplo dado (embora eu aceite, pode haver razões para não fazer isso em algumas situações).

    
por 05.09.2014 / 09:30
fonte
0

Eu acho que uma resposta que te leva a todo o comportamento que você quer com a sobrecarga de código zero é usar uma série Pandas. Ele suporta o acesso por índice, acessando pelo nome do campo (ie .x e .y), e também suporta operações elementares prontas para uso, assim você poderá adicionar e subtrair suas coordenadas sem sobrecarregar nenhum operador. .

    
por 28.09.2014 / 23:25
fonte
0

Eu daria uma olhada na classe namedtuple * da biblioteca padrão. É basicamente uma forma automatizada de subclassificar uma tupla com propriedades nomeadas para corresponder a cada campo.

Se você precisar fazer operações vetoriais e matriciais, talvez queira examinar o NumPy, que é feito de tipos de dados numéricos altamente funcionais:

por 29.09.2014 / 01:11
fonte
0

Com que frequência você usará x sem y ou vice-versa? Se sua resposta for raramente ou nunca, agrupe-as em uma tupla ou classe. Se usar uma tupla ou classe é outra questão. Uma regra comum é usar uma classe se ela tiver dois ou mais métodos e, caso contrário, usar uma tupla. Um namedtuple vai te dar a conveniência de nomear membros da classe, sendo tão leve quanto tuplas normais.

Esta resposta fala de usar namedtuple com pontos, como no seu exemplo.

    
por 30.09.2014 / 01:37
fonte
0

Existem várias regras que uso ao fazer isso. Eles se aplicam a todos os tipos de coisas, não apenas às coordenadas xey, mas também aos critérios de pesquisa, conjuntos de sinalizadores, conjuntos de parâmetros numéricos e assim por diante.

Dito isso, nem todo mundo usa esses princípios e muitas vezes você pode encontrar códigos de alta qualidade que tomam outras decisões.

Quatro ou mais parâmetros geralmente devem ser refatorados em objetos

Se a sua função tiver quatro ou mais parâmetros, tente refatorá-los em objetos que os agrupem.

O motivo é que quatro parâmetros para uma função geralmente são simplesmente demais . Em uma chamada de função, fica difícil rastrear quais argumentos são destinados a quais parâmetros, especialmente se alguns parâmetros assumem um valor padrão ou são opcionais.

Linhas de código como estas são bastante frustrantes de se ver:

SomeMethod(1, null, null, 1, 0)
SomeMethod(1, 1, 1, null, 5)

Em linguagens que suportam parâmetros formais nomeados, isso é um problema menor. Mas geralmente as pessoas não se importam em especificar o nome de um parâmetro quando não precisam.

Além disso, se após a refatoração você ainda estiver enfrentando uma função com quatro ou mais parâmetros, provavelmente terá problemas maiores.

Conjuntos de 2+ parâmetros que aparecem frequentemente juntos devem ser refatorados em objetos

Este caso toca no caso das coordenadas, pois em um projeto que envolve coordenadas, você geralmente terá que definir várias funções que os utilizam como parâmetros.

Se esses parâmetros aparecerem com tanta frequência nas chamadas de método, provavelmente haverá um strong vínculo entre eles.

Conjuntos de parâmetros que controlam a funcionalidade extensível devem ser colocados em um objeto

Por exemplo, se você tiver um método como:

Search(string name, int age, DateTime date, ...)

Quando faz sentido que a lista de parâmetros seja estendida com a adição de outros critérios, você deve colocar o conjunto de critérios em um objeto.

    
por 01.08.2017 / 13:33
fonte
0

Se o desempenho for de extrema importância, armazene-os como duas variáveis. Isso significa que menos objetos de heap são alocados e, portanto, os custos indiretos de coleta de lixo são menores.

É claro, o OP perguntou sobre o Python para que o OP provavelmente não se importasse muito com o desempenho, mas alguém pode estar lendo isso e usando, por exemplo, Java, em cujo caso o desempenho pode ser importante.

Array (ou para Python, tupla) pode ser usado se você tiver um plano para estender o código de 2 dimensões para N dimensões. Caso contrário, não se incomode.

    
por 01.08.2017 / 15:08
fonte