3

After using Django for a while, I got use to using classes without def __init__(self): ... when declaring variables. I used to declare my variables in the __init__ function, I now realize that there are cases where don't need to, I'm just unclear on when to use it or not. It seems there is a problem when trying to pass a class to a variable, should I use init in these cases?

I know I could just use __init__ for all cases, but it just makes my short classes like cleaner without it, so I would like to know when I can and cannot use it.

example:

class BaseScraper(object):
 # whithout __init__, passing Site() to site wont work.
 # site = Site()
 # parser = None
 def __init__(self):
 self.site = Site()
 self.parser = None 
class Site(object):
 # no trouble declaring url as a str
 url = ""
 def set(self, url):
 self.url = url
 def get(self):
 return self.url
if __name__ == "__main__":
 scraper = BaseScraper()
 scraper.site.set('http://www.google.com') 
 print scraper.site.get()
asked May 14, 2013 at 22:39
3
  • 1
    Django doesn't really represent Python. Django model fields are class-level attributes, they are in fact actual objects that aren't at all "holders" for your data, and they serve as medatada that the base Model's __init__() method (or some other part of that wad of code) uses to automagically create instance-level attributes and do a bunch of other stuff. Python doesn't normally work that way. Commented May 14, 2013 at 22:44
  • 1
    When initialising instance data, you should do so in __init__ unless you know what you're doing. (That class-level attributes kinda sorta act like they're default values for instance attributes is a bit of a hack with a bunch of caveats.) Commented May 14, 2013 at 22:46
  • that's pretty interesting, thanks for explaing Commented May 14, 2013 at 22:48

2 Answers 2

6

Attributes declared in the class are owned by the class rather than by individual instances of the class. In your site example, url is no more a property of individual Site objects than set or get are. For this kind of example, you want instance data - which you can initialize in __init__.

Python: Difference between class and instance attributes has a good discussion of the differences.

answered May 14, 2013 at 22:42
Sign up to request clarification or add additional context in comments.

Comments

1

This fails because Site class is not defined yet. And (as @Peter DeGlopper) said, there is a big difference between class variables and instance variables.

class BaseScraper(object):
 # This fails!
 site = Site()
 parser = None
class Site(object):
 # no trouble declaring url as a str
 url = ""
 def set(self, url):
 self.url = url
 def get(self):
 return self.url

When the virtual machine compile a python module, read and compile everything in class declaration, but on method declaration (like def __init__(...):) only read this line, ignoring the method body.

Example:

class Foo(object):
 bar1 = "bar"
 foo1 = "foo"
 def __init__(self):
 self.bar2 = "BAZ"
foo = Foo #Put a class in a veriable? yes, you can.
foo.bar1 # returns "bar"
foo.foo1 # returns "foo"
foo.bar2 # fails!!!! This will be a instance variable, but doesn't exist yet
foo2 = Foo() # Here the __init__ is called
foo2.bar2 # returns "BAZ"
foo2.bar1 #Returns "bar" because all class variables are availables from instances

Hope this helps =)

answered May 14, 2013 at 22:54

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.