2

As it was unclear earlier I am posting this scenario:

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

Now in a task queue like rq

from rq import Queue
from worker import conn

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

I want to know what this what_function would be? I remembered Django does something similar with their CBVs so I used that analogy but it wasn't so clear.


I have a class like

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

I need to past this to a task queue, so I can do something like

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

I'd want to know what other method is there to do this, for example, Django does it in their Class Based Views,

class YourListView(ListView):
    #code for your view

which is eventually passed as a function

your_view = YourListView.as_view()

How is it done?

Edit: to elaborate, django's class based views are converted to functions because the argument in the pattern function expects a function. Similarly, you might have a function which accepts the following argument

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

but the functionality of callback_function might have been mostly implemented in a class, which has a run() method via which the process is ran.

yayu
  • 7,758
  • 17
  • 54
  • 86

1 Answers1

4

I think you're describing a classmethod:

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

which could be used like this:

call_later = MyClass.as_view

and later called:

call_later()

Most frequently, class methods are used to instantiate a new instance, for example, dict's fromkeys classmethod:

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

returns a new dict instance:

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

Update

In your example,

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

you want to know what_function could go there. I saw a very similar example from the RQ home page. That's got to be your own implementation. It's going to be something you can call with your code. It's only going to be called with that argument once, so if using a class, your __init__ should look more like this, if you want to use Scraper for your what_function replacement:

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

If you want to use a class method, that might look like this:

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

And then your what_function would be Scraper.run.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • Ok, suppose `MyClass` has an attribute `val` and I have two objects, `a = Myclass('a')` and `b = Myclass('b')` such that `a.val = 'a'` and `b.val='b'` now, if the class method is using the val attribute of the class, which one would it use? – yayu Sep 21 '14 at 05:02
  • 1
    @yayu neither, there would be an AttributeError unless you provide a class variable to the class namespace, for example, immediately under `class MyClass(object):` you have `val = None` or some other value that puts the variable `val` in the classes' namespace. – Russia Must Remove Putin Sep 21 '14 at 05:05