2013-12-11 2 views
1

Я столкнулся с странной ошибкой со шпинером, хотя вопрос является общим. Spynner - это модуль веб-браузера с поддержкой состояния для python. Он отлично работает, когда он работает, но я почти с каждым запуском я получаю отказ, говоря это -Код python не видит переменную класса, инициализированную в функции __init __()

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/spynner-2.16.dev0-py2.7.egg/spynner/browser.py", line 1651, in createRequest 
    self.cookies, 
AttributeError: 'Browser' object has no attribute 'cookies' 
Segmentation fault (core dumped) 

Проблемы здесь является его segfaulting и не позволяя мне продолжить.

Глядя на код spynner я вижу, что переменная печенье фактически инициализируется в функции __init__() для класса браузера, как это:

self.cookies = [] 

Теперь в случае неудачи его действительно говорит о том, что __init__() не запускается так как он не видит переменную cookie. Я не понимаю, как это возможно. Не ограничиваясь модулем spynner, кто-то может предположить, как объект python может потерпеть неудачу с такой ошибкой?

EDIT: Я определенно наклеил бы мой код здесь, кроме его не всех в одном месте, чтобы я мог его компактно показать. Я должен был сделать это раньше, но вот общая структура и как я создаю экземпляр и использую spynner.

# helper class to get url data 
class C: 
    def __init__(self): 
     self.browser = spynner.Browser() 

    def get_data(self, url): 
     try: 
      self.browser.load(url) 
      return self.browser.html 
     except: 
      raise 

# class that does other stuff among saving url data to disk 
class B: 
    def save_url_to_disk(self, url): 
     urlObj = C() 
     html = urlObj.get_data(url) 
     # do stuff with html 


# class that drives everything 
class A: 
    def do_stuff_and_save_url_data(self, url): 
     fileObj = B() 
     fileObj.save_url_to_disk(url) 

driver = A() 
# call this function for multiple URLs. 
driver.do_stuff_and_save_url_data(url) 

Путь я бегу это ---

# xvfb-run python myfile.py 

, вероятно, выдаёт ошибку сегментации еще что-то, что я делаю. Может быть, из-за xvfb я использую и не обрабатываю правильно? Я еще не знаю. Я должен упомянуть, что я относительно новичок в python.

Я заметил, что когда я запускаю код выше, скажу «http://www.google.com», я получаю segfault в другой раз.

+0

Как вы называете Spynner? Вы подклассифицируете браузер? –

+0

Ошибка сегментации? Что бы вы ни делали, этого не должно было быть. – user2357112

+0

Можете ли вы показать нам свой код, пожалуйста? Какой-либо код делает «del self.cookies» в любой момент? –

ответ

0

Код блока do_stuff_and_save_url_data() не использовать ссылку self:
то выполнение этой функции не зависит от driver.

Код блока save_url_to_disk() также не использовать ссылку self:
то выполнение этой второй функции не зависит от объекта fileObj.

только код блок get_data() использует ссылку self, а точнее ссылку self.browser:
поэтому его выполнение и результат зависят от атрибута browser экземпляра urlObj из класса C. Этот атрибут фактически представляет собой экземпляр браузера с именем browser класса spynner.Browser.

В конце концов вы «делаете материал с html» только с данными, полученными spynner.Browser().html. И создание driver и fileObj не являются обязательными в любом случае.

.

Другое дело, что
когда команда driver.do_stuff_and_save_url_data(url) выполняется,
метод driver.do_stuff_and_save_url_data(url) сначала создается, а затем выполняется, и, наконец, «уничтожены» (точнее забыл где-то в оперативной памяти), так как он не был присвоенный любому идентификатору.

Затем идентификатор fileObj, который представляет собой идентификатор, принадлежащий к локальному пространству имен функции driver.do_stuff_and_save_url_data(), теряется тоже, что означает, что экземпляр fileObj класса B не также теряется для скрытых использования, так как он больше не присвоен идентификатор в живых.

Это то же самое для save_url_to_disk():
после создания и выполнения метода fileObj.save_url_to_disk(url), объект urlObj класса C, который содержит экземпляр браузера (объект, созданный spynner.Browser()), теряются: сотворенное браузер и все его данные потеряны.

Интересно, если это не из-за это уничтожение экземпляра браузера после каждого выполнения do_stuff_and_save_url_data() и save_url_to_disk(), что информация печенья не будет уничтожена перед скрытым вызовом.

.

Так что, на мой взгляд, ваш код вводит две функции в два определения классов A и B, и они используются как рассматриваемые функции, а не как методы.

1/Я не думаю, что это хороший шаблон кодирования. Когда вы хотите только простые функции, они должны быть написаны вне любого класса.

2/Проблема в том, что если операции запускаются функциями, каждый новый браузер создается каждый раз, когда эти функции активируются, даже если у них есть мантия методов.

Вы скажете мне, что вы хотите, чтобы эти функции действовали с данными, предоставленными браузером, определенными spynny.Browser().
Вот почему я считаю, что они не должны быть функциями, вложенными в классы, как сейчас, а реальными методами, связанными с устойчивым экземпляром браузера. Это цель объекта сохранить в том же пространстве имен данные и инструменты для обработки данных.

-

.

Все, что сказал, я бы Personnally написать:

class C(spynner.Browser): 
    def __init__(self): 
     spynner.Browser.__init__(self) 

    def get_data(self, url): 
     try: 
      self.html = self.load(url).html 
     except: 
      raise 

    # method that does other stuff among saving url data to disk 
    def save_url_to_disk(self, url): 
     get_data(url) 
     # do stuff with self.html 

    # method that drives everything 
    def do_stuff_and_save_url_data(self, url): 
     self.save_url_to_disk(url) 


driver = C() 
driver.do_stuff_and_save_url_data(url) 

Но я не уверен иметь хорошо undesrtood все свои соображения, и я предупреждаю, что я не знаю, spynner перед чтением пост. Все, что я написал, может быть глупо относительно вашей реальной проблемы. Пожалуйста, обратите внимание на мой пост.