Что более эффективно: использовать объект в качестве атрибута класса?Или переинициализировать при необходимости? - PullRequest
0 голосов
/ 11 февраля 2019

Я строю паук / скребок с помощью Scrapy, и мне было интересно, что будет более эффективным: инициализировать объект-оболочку API один раз как атрибут класса?Или повторно инициализировать с каждым запросом URL?Мне интересно в контексте общей эффективности и памяти (утечек), поскольку это будет довольно большой проект (миллионы запросов).

Случай 1 :

# init API wrapper ONCE as class attribute
class ScrapySpider():

    api = SomeAPIWrapper()

    urls = [
        'https://website.com',
        # ... +1mil URLs
    ]

    def request(self):
        for url in urls:
            yield Request(url)

    def parse(self, response):
        yield self.api.get_meta(response.url)

Дело 2 :

# init new API wrapper on EACH request
class ScrapySpider():

    urls = [
        'https://website.com',
        # ... +1mil URLs
    ]

    def request(self):
        for url in urls:
            yield Request(url)

    def parse(self, response):
        api = SomeAPIWrapper()
        yield api.get_meta(response.url)

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Нет универсального, универсального ответа на этот вопрос - это зависит от того, насколько дорогостоящим является создание экземпляра объекта, как часто вы заканчиваете его созданием в лучшем / среднем / худшем случае, а в вашем примере используетсяатрибут класса (вместо атрибута экземпляра), безопасно ли разделять этот объект среди всех экземпляров класса хоста.

Обратите внимание, что к альтернативе есть два других термина:

1/ атрибут для каждого экземпляра, созданный в инициализаторе:

class ScrapySpider():

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        self.api = SomeAPIWrapper()

, который позволяет избежать проблем одновременного доступа, которые могут возникнуть при использовании атрибута класса, и

2 / кэшированное свойство

class ScrapySpider():

    @property
    def api(self):
        if not hasattr(self, "_cached_api"):
            self._cached_api = ApiWrapper()
        return self._cached_api

, который также предотвращает создание экземпляра ApiWrapper до того, как он понадобится (может быть полезно, если его создание стоит дорого и не всегда необходимо), но добавляет небольшие накладные расходы при доступе к атрибутам.

0 голосов
/ 11 февраля 2019

В примере кода использование атрибута класса (Случай 1) должно быть более эффективным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...