Как представить класс в виде функции?
Как было неясно ранее, я публикую этот сценарий:
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 ответ:
Я думаю, что вы описываете
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'sfromkeysclassmethod: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.