Python: загадочное поведение внутри httplib - PullRequest
0 голосов
/ 14 марта 2010

Я добавил одну строку (import pdb; pdb.set_trace()) в HTTPlib HTTPConnection.putheader, чтобы видеть, что происходит внутри

Python26\Lib\httplib.py, строка 489:

def putheader(self, header, value):
    """Send a request header line to the server.

    For example: h.putheader('Accept', 'text/html')
    """
    import pdb; pdb.set_trace()
    if self.__state != _CS_REQ_STARTED:
        raise CannotSendHeader()

    str = '%s: %s' % (header, value)
    self._output(str)

затем запустил это от переводчика

import urllib2
urllib2.urlopen('http://www.ioerror.us/ip/headers')

... и, как и ожидалось, PDB начинает:

> c:\python26\lib\httplib.py(858)putheader()
-> if self.__state != _CS_REQ_STARTED:
(Pdb)

в PDB я могу оценивать выражения на лету, поэтому я попытался ввести self.__state:

(Pdb) self.__state
*** AttributeError: HTTPConnection instance has no attribute '__state'

Увы, __state этого экземпляра нет. Однако, когда я ввожу step, отладчик выходит за пределы

if self.__state != _CS_REQ_STARTED:

строка без проблем. Почему это происходит? Если self.__state не существует, Python должен будет вызвать исключение, как это было, когда я вводил выражение.

Версия Python: 2.6.4 на win32

Ответы [ 2 ]

1 голос
/ 14 марта 2010

Отвечая на мой вопрос:

http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_Python

__state - это личное имя внутри объекта, оно искажается как _HTTPConnection__state, поэтому, когда я хочу получить к нему доступ в PDB, я должен назвать его как self._HTTPConnection__state. Только объект может ссылаться на него как __state.

0 голосов
/ 14 марта 2010

Если состояние self .__ не существует, python должен был бы вызвать исключение, как это было, когда я вводил выражение.

В Python вам не нужно явно объявлять переменные. Они «рождаются», когда вы их назначаете.

Некоторые валидаторы кода, такие как pylint, предупреждают об этих ситуациях. В вашем случае вы могли бы иметь что-то вроде self.__state = None в HTTPConnection.__init__()

но это не очень важно.

...