2

I try to run a class method in Python 3 every n seconds.

I thought that Threading would be a good approach. The question (Run certain code every n seconds) shows how to do that without objects.

I tried to "transfer" this code to OOP like this:

class Test:
    import threading
    def printit():
        print("hello world")
        threading.Timer(5.0, self.printit).start()

test = Test()
test.printit()

>> TypeError: printit() takes no arguments (1 given)

I get this error.

Can you help me doing it right?

Community
  • 1
  • 1
speendo
  • 13,045
  • 22
  • 71
  • 107
  • 1
    Your method is incorrectly defined. You're missing the self parameter – Asad Saeeduddin Nov 14 '14 at 23:38
  • you're right. I'm a bit ashamed :O – speendo Nov 14 '14 at 23:41
  • 2
    Happens to everyone at one point or another. What you've defined is a static method. If your class really doesn't contain any data, and only has this method, you should leave the definition as is and use `Test.printit()` – Asad Saeeduddin Nov 14 '14 at 23:47
  • 1
    As a side note, you really don't want to do an `import` inside a class definition. (There are some rare cases where it might make sense, but this isn't one of them.) Do it at the top level, at the top of your script. – abarnert Nov 15 '14 at 00:09
  • @Asad: No, he hasn't defined a static method; you need to add `@staticmethod` for that. What he's defined is an instance method that can't be called on an instance. Your suggestion does generally _work_, but it's misleading. – abarnert Nov 15 '14 at 00:10
  • @abarnert No, he has very much defined a static method, at least in the sense of how static methods are defined in most languages, i.e a method which is invoked against the type/class it is defined in, and not an instance thereof. Whether he applies the convenience staticmethod decorator is immaterial (it simply wraps the actual static method with a function that gracefully resolves instance invocations) – Asad Saeeduddin Nov 15 '14 at 00:32
  • @Asad: "How static methods are defined in most languages" is irrelevant to Python, which has its own definition of static methods. What he's defined is a method that can't actually be called as a method; because unbound methods (what a descriptor returns when you look up the attribute on the class itself) are represented as plain functions in Python 3.x (but not 2.x), it can, coincidentally, be called as an unbound method. – abarnert Nov 15 '14 at 01:39
  • 1
    This is Python 3.x the OP is talking about, there are no unbound functions. Fair enough about Python having it's own definition, but I feel this usage is completely on its head. "A callable member of a class that does not and cannot access an instance of the class, and can be invoked via a reference to the class, is not a static method. Instead, it is an uncallable instance method. It is only a static method once you apply this decorator we give you that uncurries it and muddles up the call signature so it can be invoked as an instance method." Doesn't make a lot of sense to me. – Asad Saeeduddin Nov 15 '14 at 01:52

1 Answers1

3

Add the argument self into the printit method, and it works for me. Also, import statements should be at the top of the file, not within the class definition.

import threading

class Test:
    def printit(self):
        print("hello world")
        threading.Timer(5.0, self.printit).start()

test = Test()
test.printit()
mdadm
  • 1,333
  • 1
  • 12
  • 9