Z funkcją print() użytkownik Pythona zapoznaje się już na początku swojej przygody z tym językiem. Jest ona integralną częścią pierwszego pisanego w tym języku programu, czyli print(„Hello world”). Z pozoru wydaje się też najprostszą funkcją wbudowaną tego języka, która po prostu wyświetla komunikaty na ekranie. Jednak tak naprawdę zmiany wprowadzone w sposobie jej działania w wersji 3.x są główną przyczyną, dla której kod z programów w wersji 2.x może po prostu… nie działać.

Wbudowana funkcja print()  wyświetla komunikaty na ekranie, a mówiąc bardziej oficjalnie, jest to interfejs dla standardowego strumienia wyjścia. Print() działa w ten sposób, że przekształca  obiekt na tekst, dodaj odpowiednie formatowanie, a następnie przesyła komunikat do strumienia wyjścia. Dlatego obiekty wyświetlane za pomocą tego polecenia nie muszą być wcześniej konwertowane na obiekty tekstowe. Strumień wyjścia, określany jako stdout, jest to mechanizm systemu, który wypisuje wyniki zwracane przez programy. Jest on mapowany do terminala, gdzie został uruchomiony program. Istnieje również możliwość przekierowania strumieniu wyjścia do pliku lub potoku. Razem ze strumieniem wejścia oraz strumieniem błędów, strumień wyjście wchodzi w skład trzech kanałów komunikacyjnych, jakie są tworzone podczas uruchamiania skryptu. Wszystkie przynależą do modułu sys będącego częścią biblioteki standardowej.

Wyświetlanie tekstu w Pythonie 3.x znacząco różni się od wyświetlania tekstu w wersji 2.x. Jest to jedna z najczęstszych przyczyn, dla których skrypty napisane w starszej wersji nie mogą być odpalone przy użyciu interpretera dla nowszej wersji. W Pythonie 3.x print() jest tak naprawdę funkcją wbudowaną, w której można używać argumentów ze słowami kluczowymi, dzięki czemu  komunikaty są w łatwy sposób formatowane. Natomiast w poprzednich wersjach print jest instrukcją, która posiada swoją własną składnię.

Print w wersji Python 3.x

W tej wersji Pythona do wyświetlania tekstów wykorzystuje się funkcję print() w taki sam sposób jak każdą inną funkcję. Ważne jest to, aby używać tej funkcji bez przypisywania zwracanej wartości do zmiennej, jako że print() zwraca po prostu None. Formatowanie komunikatu, na przykład pod względem rodzaju separatorów lub typu znaku końca wiersza odbywa się poprzez przekazanie odpowiednich argumentów ze słowami kluczowymi. Domyślnie separatorem jest spacja, a znak końca wiersza to nowa linia.

Print w wersji Python 2.x

We wcześniejszej wersji Pythona print było wykorzystywane jako instrukcja. Przy użyciu specjalnej składni możliwe było przekierowanie jej wyników do pliku lub pomijanie znaku nowego wiersza. Nie pozwalała za to na definiowanie własnych separatorów.

Forma wywołania – print w wersji Python 3.x

Wywołanie funkcji Print w Pythonie 3.x odbywa się przy użyciu poniższej formy:

print(object, sep= ’ ’, end=’\n’, file=sys.stdout, flush=False)

Oczywiście jest to forma domyślna, nie musimy za każdym razem wypisywać znaku separatora lub nowego wiersza. Jeśli chcemy wprowadzić własne ustawienia w zakresie któregokolwiek z argumentów: sep, end, file czy flush, musimy podać wartość wraz ze słowem kluczowym, jak na przykład:

>>> print('Python', 3, sep='#$#')

Python#$#3

Co oznacza każdy z argumentów?

  • sep jest to ciąg znaków ustawiony pomiędzy wyświetlanymi obiektami, domyślnie jest to jedna stacja,
  • end określa znak, jaki będzie dołączony na końcu wyświetlanego tekstu:
>>> print('Python', 3, end='#$#')

Python 3#$#>>>

file jest to obiekt typu plikowego, taki jak strumień standardowy lub plik, gdzie zostanie wysłane wyświetlany tekst. Jako argument można przekazać dowolny obiekt plikowy, który obsługuje metodę write():

>>> import sys

>>> sys.stdout.write('Coś tam')

Coś tam7 #liczba na końcu komunikatu zwrotnego określa, ile znaków zostało zapisanych

Jeśli jest to plik, to wcześniej należy go otworzyć do zapisu.

>>> file=open('test_print.txt', 'w')

>>> print('test', file=file)

>>> file.close()

>>> print(open('test_print.txt').read())

test
  • flush określa, czy opróżnienie do bufora wyjściowego ma być natychmiastowe.

Obiekt, który ma zostać wyświetlony lub przekazany do pliku, jest również wcześniej konwertowany za pomocą wbudowanej funkcji str(). Brak przekazania jakiegokolweik argumentu do funkcji print powoduje wysłanie do standardowego strumienia wyjścia znaku nowego wiersza i taki też wynik jest drukowany na ekranie.

Instrukcja print w Pythonie 2.x

>>> x = 'abc’

We wcześniejszej wersji Pythona instrukcja print ma własną składnię, która nie pozwala jednak na określenie własnego separatora. W praktyce wygląda to w ten sposób, że instrukcja może przeprowadzić działania takie jak: wypisanie komunikatu przy użyciu standardowego wyjścia, użycie tekstowych reprezentacji obiektów, oddzielenie ich spacją oraz umieszczenie znaku końca wiersza na końcu obiektu.

>>> y = 'xyz'

>>> print x, y

abc xyz

Umieszczenie przecinka na końcu instrukcji pozwala na uniknięcie dodawania znaku nowego wiersza na końcu w ciągu znaków. Porównaj:

>>> print x, y; print x

abc xyz

abc

>>> print x, y,; print x

abc xyz abc

Przekierowanie obiektu do pliku:

>>> file=open('test.txt', 'w')

>>> print >> file, x, y

>>> file.close()

>>> import os

>>> os.getcwd()

Żeby ustawić własny separator należy korzystać z formatowania ciągu znaków:

>>> print "%s &^& %s" % (x, y)

abc &^& xyz

Przekierowanie strumienia wyjścia

Możliwość przekierowywania strumienia wyjścia pozwala na zapisanie komunikatu w innym miejscu niż standardowy strumień wyjścia, czyli terminal, a najczęściej po prostu ekran komputera. Przekierowanie strumienia może być przeprowadzone jednorazowo przy wywołaniu pojedynczej instrukcji print lub poprzez przypisanie zmiennej sys.stdout do obiektu „na stałe”, tak jak na przykład w przypadku poniższego pliku:

>>> import sys

>>> sys.stdout=open('testing_print.txt', 'w')

>>> print('test test')

>>> sys.stdout.close()

Komunikat został zapisany w pliku, do którego dostęp możemy mieć jednak tylko poprzez wejście do odpowiedniego katalogu, jako że zamknęliśmy strumień wyjścia.

>>> myfile = open('testing_print.txt')

>>> myfile.read()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

ValueError: I/O operation on closed file.

Jeśli  w dalszej części kodu chce się wyświetlać komunikaty w standardowym strumieniu wyjścia, czyli na ekranie, to ważne jest pamiętanie o tym, aby zapisać „oryginalny” obiekt strumienia wyjścia do innej zmiennej zanim przypisze się do niego inny obiekt.

>>> import sys

>>> sys_stdout = sys.stdout

>>> sys.stdout = open('testing_print.txt', 'w')

>>> print('testing again!')

>>> sys.stdout.close()

>>> sys.stdout = sys_stdout

>>> print(open('testing_print.txt').read())

testing again!

Oczywiście w wersji Pythona 3.x można zawsze skorzystać z argumentu file funkcji print, gdzie podaje się obiekt mający być strumieniem wyjścia. Takie rozwiązanie jest przydatne wtedy, gdy chce się dokonać tymczasowej zmiany; na zmianę wypisywać komunikat na ekranie lub przekierowywać komunikat do pliku.

>>> file = open('testing_print.txt', 'a')

>>> print('and again', file=file)

>>> file.close()

>>> print(open('testing_print.txt').read())

testing again!

and again

Funkcja print może być także wykorzystywana do zapisywania wyników o błędach zarówno na ekranie, jak i w pliku. Strumień wyjścia błędów jest przypisany do zmiennej sys.stderr.

>>> print('błąd', file=sys.stderr)

błąd

>>> 

>>> sys.stderr = open('testing_err.txt', 'w')

>>> 3/0

>>> sys.stderr.close()

>>> print(open('testing_err.txt').read())

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

ZeroDivisionError: division by zero

Jak widzimy komunikat o błędzie w ostatnim przykładzie został zapisany we wskazanym pliku.

Print: róznice między wersjami Python 3.x i Python 2.x – jak je zneutralizować?

Żeby zniwelować różnice w działaniu instrukcji Print w nowej i starej wersji Pythona można skorzystać z kilku sposobów.

  • użycie konwertera 2to3, jeśli chcemy, aby kod napisany w Pythonie 2.x działało w wersji 3.x. Analogicznie dla odwrotnej sytuacji można użyć konwertera 3to2.
  • import funkcji print_function z modułu __future__, który sprawia, że funkcja Print z wersji 2x działa tak samo jak w wersji 3x.
    • Funkcja print w Pythonie 2.x pozornie działa wówczas tak jak w wersji 3.x:
>>> print 'test'

test

>>> print('test')

test

Jednak jeśli chcemy wydrukować na ekranie więcej niż jeden łańcuch znaków, różnica jest wówczas widoczna – print użyte z nawiasami zwraca krotkę:

>>> print 'test', 'test2'

test test2

>>> print('test', 'test2')

('test', 'test2')

 

Import funkcji z modułu future pozwala 'przywrócić’ zachowanie takie jak w wersji 3.x:

>>> from __future__ import print_function

>>> print('test', 'test2')

test test2

Funkcja print przestaje również również działać jak w wersji 2.x:

>>> print 'test', 'test2'

  File "<stdin>", line 1

    print 'test', 'test2'

               ^

SyntaxError: invalid syntax

Alternatywą jest korzystanie z formatowania. Wówczas nie trzeba pamiętać o imporcie jakichkolwiek modułów – poniższy kod został wywołany w interpreterze Pythona 2.7:

>>> print('% s, %s, %.1f' % ('Python', 'wersja', 2.7))

Python, wersja, 2.7

>>> print('{0}, {1}, {2}'.format('Python', 'wersja', 2.7))

Python, wersja, 2.7

W następnym wpisie przejdziemy do testów prawdziwości oraz testów logicznych przy użyciu instrukcji if.