[EDIT 00]: Edytowałem kilka razy post, a teraz nawet tytuł, przeczytaj poniżej.Implementacja interpolacji ciągów znaków Python
Właśnie dowiedziałem się o metodzie format string, a jego stosowanie ze słowników, jak te świadczone przez vars()
, locals()
i globals()
, przykład:
name = 'Ismael'
print 'My name is {name}.'.format(**vars())
Ale chcę zrobić:
name = 'Ismael'
print 'My name is {name}.' # Similar to ruby
Więc wpadłem na to:
def mprint(string='', dictionary=globals()):
print string.format(**dictionary)
można wchodzić w interakcje z kod tutaj: http://labs.codecademy.com/BA0B/3#:workspace
Wreszcie, co chciałbym zrobić, to mieć funkcję w innym pliku, o nazwie my_print.py
, więc mogłem zrobić:
from my_print import mprint
name= 'Ismael'
mprint('Hello! My name is {name}.')
ale jak to jest teraz, istnieje problem z zakresami, w jaki sposób mogę uzyskać obszar nazw głównego modułu jako słownik z importowanej funkcji mprint. (nie ten z my_print.py
)
Mam nadzieję, że zrobiłem sobie spokój, jeśli nie, spróbuj zaimportować funkcję z innego modułu. (traceback jest w łączu)
Dostęp do dyktafonu globals()
od my_print.py
, ale oczywiście nazwa zmiennej nie jest zdefiniowana w tym zakresie, żadnych pomysłów, jak to osiągnąć?
Funkcja działa, jeśli jest zdefiniowana w tym samym module, ale zauważ, że muszę użyć globals()
, ponieważ jeśli nie, to dostanę tylko słownik z wartościami z zakresu mprint()
.
Próbowałem używać nielokalnej i notacji kropkowej, aby uzyskać dostęp do zmiennych głównych modułu, ale nadal nie mogę tego rozgryźć.
[EDIT 01]: Myślę, że zorientowali się rozwiązanie:
W my_print.py:
def mprint(string='',dictionary=None):
if dictionary is None:
import sys
caller = sys._getframe(1)
dictionary = caller.f_locals
print string.format(**dictionary)
W test.py:
from my_print import mprint
name = 'Ismael'
country = 'Mexico'
languages = ['English', 'Spanish']
mprint("Hello! My name is {name}, I'm from {country}\n"
"and I can speak {languages[1]} and {languages[0]}.")
Drukuje:
Hello! My name is Ismael, I'm from Mexico
and I can speak Spanish and English.
Jak myślisz, chłopaki? To było dla mnie trudne!
Lubię to, o wiele bardziej czytelne dla mnie.
[Edycja 02]: wprowadzonych modułu z interpolate
funkcji, klasy Interpolate
i próbą dla sposobu interpolate
klasy analogiczny do funkcji.
Ma mały pakiet testowy i jest udokumentowany!
Utknąłem z wdrożenia metody, nie rozumiem.
Oto kod: http://pastebin.com/N2WubRSB
Co sądzisz faceci?
[EDIT 03]: Ok mam rozliczane tylko z funkcji interpolate()
teraz.
W string_interpolation.py
:
import sys
def get_scope(scope):
scope = scope.lower()
caller = sys._getframe(2)
options = ['l', 'local', 'g', 'global']
if scope not in options[:2]:
if scope in options[2:]:
return caller.f_globals
else:
raise ValueError('invalid mode: {0}'.format(scope))
return caller.f_locals
def interpolate(format_string=str(),sequence=None,scope='local',returns=False):
if type(sequence) is str:
scope = sequence
sequence = get_scope(scope)
else:
if not sequence:
sequence = get_scope(scope)
format = 'format_string.format(**sequence)'
if returns is False:
print eval(format)
elif returns is True:
return eval(format)
Jeszcze raz dziękuję wam! Jakieś opinie?
[EDIT 04]:
To moja ostatnia wersja, ma testów, docstrings i opisuje pewne ograniczenia Znalazłem: http://pastebin.com/ssqbbs57
Można szybko przetestować kod tutaj : http://labs.codecademy.com/BBMF#:workspace
A klon Grom git repo tutaj: https://github.com/Ismael-VC/python_string_interpolation.git
related: [? Czy formater ciąg, który ciągnie zmienne z jego wywołującego zakres złej praktyki] (http://stackoverflow.com/questions/13312240/is- a-string-formatter-that-pulls-variables-from-its-calling-scope-bad-practice) – jfs
pokrewne: [drukowanie nazw zmiennych i zawartości jako narzędzie do debugowania; szukanie skrótu emacs/Python] (http://stackoverflow.com/questions/2813227/printing-variable-names-and-contents-as-debugging-toollooking-for-emacs-python) – jfs
To jest ciekawe ćwiczenie , ale ostrzegam przed tego rodzaju niejawnym zachowaniem: Python zniechęca go ("Jawny jest lepszy niż niejawny" oznacza tutaj, że 'mprint (" ... ", vars())' jest lepszy niż 'mprint (" ... ') " wróć do dzwoniącego i uzyskaj jego lokalne zmienne) i myślę, że robi to z ważnych powodów (wyraźny kod jest prawdopodobnie łatwiejszy do odczytania i utrzymania). – EOL