Как представить класс в виде функции?


Как было неясно ранее, я публикую этот сценарий:

class Scraper:
    def __init__(self,url):
      self.start_page = url

    def parse_html(self):
      pass

    def get_all_links(self):
      pass

    def run(self):
      #parse html, get all links, parse them and when done...
      return links

Теперь в очереди задач типа rq

from rq import Queue
from worker import conn

q = Queue(connection=conn)
result = q.enqueue(what_function, 'http://stackoverflow.com')

Я хочу знать, что это будет за функция what_function? Я вспомнил, что Django делает что-то подобное с их CBV, поэтому я использовал эту аналогию, но она была не столь ясной.


У меня есть такой класс, как

class A:
    def run(self,arg):
        #do something

Мне нужно передать это в очередь задач, чтобы я мог сделать что-то вроде

a = A()
b = a.run
# q is the queue object
q.enqueue(b,some_arg)

Я хотел бы знать, какой еще метод существует для этого, например, Django делает это в своих классовых представлениях,

class YourListView(ListView):
    #code for your view

, которая в конечном итоге передается как функция

your_view = YourListView.as_view()

Как это делается?

Edit: чтобы уточнить, представления на основе классов django преобразуются в функции, потому что аргумент в функции pattern ожидает функцию. Аналогично, у вас может быть функция, которая принимает следующий аргумент

task_queue(callback_function, *parameters):
    #add to queue and return result when done

Но функциональность callback_function, возможно, была в основном реализована в классе, который имеет метод run (), с помощью которого процесс запущен.

1 2

1 ответ:

Я думаю, что вы описываете classmethod:

class MyClass(object):
    @classmethod
    def as_view(cls):
        '''method intended to be called on the class, not an instance'''
        return cls(instantiation, args)

Который можно использовать следующим образом:

call_later = MyClass.as_view

И позднее назывался:

call_later()

Чаще всего для создания нового экземпляра используются методы класса, например, dict's fromkeys classmethod:

dict.fromkeys(['foo', 'bar'])

Возвращает новый экземпляр dict:

{'foo': None, 'bar': None}

Обновление

В вашем примере,

result = q.enqueue(what_function, 'http://stackoverflow.com')

Вы хотите знать, что what_function могли бы пойти туда. Я видел очень похожий пример с домашней страницы RQ. Вот и приходится будьте своей собственной реализацией. Это будет что-то, что вы можете назвать своим кодом. Он будет вызван с этим аргументом только один раз, поэтому при использовании класса ваш __init__ должен выглядеть примерно так, если вы хотите использовать Scraper для замены what_function:

class Scraper:
    def __init__(self,url):
        self.start_page = url
        self.run()
        # etc...

Если вы хотите использовать метод класса, это может выглядеть следующим образом:

class Scraper:
    def __init__(self,url):
        self.start_page = url

    def parse_html(self):
        pass

    def get_all_links(self):
        pass

    @classmethod
    def run(cls, url):
        instance = cls(url)
        #parse html, get all links, parse them and when done...
        return links

И тогда ваш what_function будет Scraper.run.