2014-12-10 15 views
5

otrzymuję, że byłoby to możliwe, aby zrobić coś podobnegoCzy można pisać wektory w formacie i, j, k?

i = numpy.array([1,0,0]) 
j = numpy.array([0,1,0]) 
k = numpy.array([0,0,1]) 

a = 2*i + 5*j + 9*k 

ale jest to możliwe, aby wykorzystać podobną składnię do sposobu liczby zespolone są zrobione, i utworzyć klasę, która może określić 2i + 5j + 9k jest członkiem mojego klasy i automatycznie go utworzyć?

A może wymagałoby to zmiany interpretera python, zmieniając sposób, w jaki analizuje pliki? Zajrzałem do pliku gramatycznego, ale wszystko, co widzę, to aluzja do: NUMBER, a j nie jest wymienione.

Zajrzałem także pod parsermodule.c, ale nie mogłem łatwo zauważyć niczego, co sprawiło, że było oczywiste, jak można to zrobić.

Czy ktoś wie, jak to możliwe?

Powinienem chyba dodać, że tak naprawdę nie planuję tego zrobić (chyba, że ​​jakimś cudem okazało się, że nie będę wymagał rekompilacji mojej własnej wersji Pythona, co byłoby szalone, aby zrobić coś innego niż akademicką podróż) , ale tylko z ciekawości, jak działa ten język.

+0

Nie, nie jest to możliwe bez zmiany parsera Python. Dodałem znacznik "Python-internals" i już wkrótce ludzie z całego świata zbiegną się tutaj, by powiedzieć, gdzie taka zmiana musiałaby zostać wykonana (i radzę nie robić tego). – jsbueno

+0

Możesz zobaczyć, gdzie wyodrębniane są liczby złożone w ['tokenizer.py'] (https://hg.python.org/releasing/2.7.9/file/753a8f457ddc/Parser/tokenizer.c#l1429) – jonrsharpe

+0

Komentarz matematyczny : Czy twój wektor 'j' nie powinien być' numpy.array ([0,1,0]) '(druga współrzędna 1 zamiast 0)? – halex

Odpowiedz

1

Można napisać klasę, która dziedziczy numpy.ndarray (tj podklasy), które zastępuje repr metodę (który jest odpowiedzialny za kontrolowanie, w jaki sposób obiekt jest drukowany na konsoli), w następujący sposób:

import numpy 

class Vector3DDisplay(numpy.ndarray): 

def __init__(self, vector): 
    if len(vector) == 3: 
     self.vec = numpy.array(vector) 
    else: 
     raise TypeError('Vector must be of length 3.') 

def __repr__(self): 
    return str(self.vec[0])+'*i + '+str(self.vec[1])+'*j + '+str(self.vec[2])+'*k ' 

Najprawdopodobniej zauważysz tutaj oczywisty problem: rzeczywisty wektor to self.vec, a nie sam obiekt, więc wszystkie twoje numpy muszą zostać wykonane na atrybucie self.vec. Powodem jest to, że numpy tablice są napisane w taki sposób, że są trudne do podklasy (por. this question about subclassing C exentsions). Normalnie zainicjować tablicę z:

>>>> import numpy 
>>>> numpy.ndarray(vector) 

Problem polega na tym, że w rzeczywistości nie jest np.array klasy, ale funkcja fabrycznie dla klasy numpy.ndarray, który jest inicjowany inaczej i jest rzadko używany. Nie można pozwolić obiektowi dziedziczyć metod z funkcji, więc dziedziczenie nie jest proste.

+1

Ale to nie pozwoli mi ustawić go po prostu wykonując 'v = 1i + 2j + 3k' – will

+0

Czy chcesz zainicjować z ciągu" 1i + 2j + 3k "? Ponieważ możesz przeanalizować to, usuwając białe znaki i dodawanie oraz używając wyrażeń regularnych, aby wybrać odpowiednie cyfry w funkcji __init__. Jeśli * nie * chcesz, aby pochodziło z sznurka, rzeczy są o wiele bardziej skomplikowane i wykraczają poza to, co wiem z góry. – MTrenfield

+1

Nie, to byłoby łatwe. Chcę wiedzieć, czy istnieje sposób inicjowania z 'a = 4i + 2j + 65k', * bez * cudzysłowów lub czegokolwiek. Ale wierzę, że jedynym sposobem, aby to zrobić, jest zmiana python. – will