2011-10-27 8 views
17

Testowałem kod na interpretera i zauważyłem pewne nieoczekiwane zachowanie dla klasy sqlite3.Row.W jaki sposób drukowanie obiektu może mieć inne wyniki niż zarówno str(), jak i repr()?

Moje zrozumienie, że print obj będzie zawsze taki sam wynik jak print str(obj) i wpisując obj do tłumacza dostanie taki sam wynik jak print repr(obj), jednak nie jest to sprawa dla sqlite3.Row:

>>> print row  # the row object prints like a tuple 
(u'string',) 
>>> print str(row) # why wouldn't this match the output from above? 
<sqlite3.Row object at 0xa19a450> 

>>> row    # usually this would be the repr for an object 
(u'string',) 
>>> print repr(row) # but repr(row) is something different as well! 
<sqlite3.Row object at 0xa19a450> 

myślę sqlite3.Row musi być podklasą tuple, ale nadal nie rozumiem dokładnie, co dzieje się za kulisami, które mogłyby spowodować to zachowanie. Czy ktoś może to wyjaśnić?

Zostało to przetestowane na Pythonie 2.5.1, nie jest pewne, czy zachowanie jest takie samo dla innych wersji Pythona.

Nie jestem pewien, czy to ma znaczenie, ale atrybut row_factory dla mojego Connection został ustawiony na sqlite3.Row.

+0

Czy obejrzałeś http://stackoverflow.com/questions/1436703/difference-between-str-and-repr-in-python przed opublikowaniem? – ktdrv

+0

@kaloyan - Nie mogę znaleźć niczego, co by odpowiadało na moje pytanie, jeśli możesz wskazać mi to. –

+0

Interesujące zachowanie. 'sqlite3.Row' nie wydaje się podklasą krotki, więc przypuszczam, że jest to lista wyjątków i/lub krotek ze względu na inne kryteria niż dziedziczenie, ale nie mogę znaleźć niczego w dokumentacji, która by przyznała, znacznie mniej wyjaśnić to. – millimoose

Odpowiedz

11

PySqlite zapewnia specjalny rodzimy hak dla print, ale nie implementuje __repr__ ani __str__. Powiedziałbym, że to trochę stracona szansa, ale przynajmniej wyjaśnia zachowanie, które obserwujesz.

Zobacz pysqlite źródło: https://github.com/ghaering/pysqlite/blob/master/src/row.c#L241 i Python dokumentów: http://docs.python.org/c-api/typeobj.html#tp_print

+2

Nice find! Wygląda na to, że programiści sqlite poszli wbrew zaleceniom, prawdopodobnie dlatego nie jest to widoczne w większej liczbie miejsc. Z dokumentów: "Typ nigdy nie powinien implementować tp_print w sposób, który generuje inny wynik niż tp_repr lub tp_str would" i "nie zaleca się definiowania tp_print, lecz polegać na tp_repr i tp_str dla drukowania". –

+3

Połączyłem ten temat w bugtracker pysqlite: http://code.google.com/p/pysqlite/issues/detail?id=4 – Ondergetekende

+0

@Ondergetekende link błędu zepsuł się, czy skończył gdzie indziej, czy też otwórz nową (na http://bugs.python.org/?) –

0
s = str(tuple(row)) 

jest rozwiązanie, jeśli chcesz oryginalnego reprezentacji krotka ciąg.

Jest to przydatne, gdy chcesz łatwo zalogować wiersz jak w:

logging.debug(tuple(user_row)) 

działa, ponieważ wiersze są iterable.

Powiązane problemy