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