Skip to content

Instantly share code, notes, and snippets.

@oiuww09fn
Created December 7, 2013 13:49
Show Gist options
  • Save oiuww09fn/7841507 to your computer and use it in GitHub Desktop.
Save oiuww09fn/7841507 to your computer and use it in GitHub Desktop.
python class
  • When you access an attribute, the resulting value may come from several different places. For example, a.name in the previous example returns the name attribute of the instance a. However, a.deposit returns the deposit attribute (a method) of the Account class.When you access an attribute, the instance is checked first and if nothing is known, the search moves to the instance’s class instead.This is the underlying mechanism by which a class shares its attributes with all of its instances.

  • The lack of scoping in classes is one area where Python differs from C++ or Java. If you have used those languages, the self parameter in Python is the same as the this pointer. The explicit use of self is required because Python does not provide a means to explicitly declare variables (that is, a declaration such as int x or float y in C). Without this, there is no way to know whether an assignment to a variable in a method is supposed to be a local variable or if it’s supposed to be saved as an instance attribute. The explicit use of self fixes this—all values stored on self are part of the instance and all other assignments are just local variabs.

  • In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.(BaseClass().init equal super(BaseClass, self).init)

  • if it looks like, quacks like, and walks like a duck, then it’s a duck.

  • A static method is an ordinary function that just happens to live in the namespace defined by a class. It does not operate on any kind of instance. To define a static method, use the @staticmethod decorator as shown here:

      class Foo(object):
          @staticmethod def add(x,y):
          return x + y
    

    To call a static method, you just prefix it by the class name.You do not pass it any addi- tional information. For example:

      x = Foo.add(3,4) # x = 7
    

    A common use of static methods is in writing classes where you might have many dif- ferent ways to create new instances. Because there can only be one init() func- tion, alternative creation functions are often defined as shown here:

      class Date(object):
          def __init__(self,year,month,day):
              self.year = year self.month = month self.day = day
          @staticmethod 
          def now():
              t = time.localtime()
              return Date(t.tm_year, t.tm_mon, t.tm_day) 
          @staticmethod
          def tomorrow():
              t = time.localtime(time.time()+86400) 
              return Date(t.tm_year, t.tm_mon, t.tm_day)
    

    Example of creating some dates

      a = Date(1967, 4, 9)
      b = Date.now() # Calls static method now()
      c = Date.tomorrow() # Calls static method tomorrow()
    
  • Class methods are methods that operate on the class itself as an object. Defined using the @classmethod decorator, a class method is different than an instance method in that the class is passed as the first argument which is named cls by convention. For example:

      class Times(object): 
          factor = 1
          @classmethod 
          def mul(cls,x):
              return cls.factor*x
      class TwoTimes(Times): 
          factor = 2
      
    
      x = TwoTimes.mul(4) # Calls Times.mul(TwoTimes, 4) -> 8
    

    In this example, notice how the class TwoTimes is passed to mul() as an object. Although this example is esoteric, there are practical, but subtle, uses of class methods. As an example, suppose that you defined a class that inherited from the Date class shown previously and customized it slightly:

      class EuroDate(Date):
          #Modify string conversion to use European dates 
          def __str__(self):
              return "%02d/%02d/%4d" % (self.day, self.month, self.year)
    

    **Because the class inherits from Date, it has all of the same features. However, the now()and tomorrow() methods are slightly broken. For example, if someone calls EuroDate.now(), a Date object is returned instead of a EuroDate object. A class method can fix this:

      class Date(object): 
          ...
          @classmethod 
          def now(cls):
              t = time.localtime()
              # Create an object of the appropriate type 
              return cls(t.tm_year, t.tm_month, t.tm_day)
      class EuroDate(Date): 
          ...
    
      
      a = Date.now() # Calls Date.now(Date) and returns a Date
      b = EuroDate.now() # Calls Date.now(EuroDate) and returns a EuroDate
    

    One caution about static and class methods is that Python does not manage these meth- ods in a separate namespace than the instance methods. As a result, they can be invoked on an instance. For example:

      a = Date(1967,4,9)
      b = d.now() # Calls Date.now(Date)
    

    This is potentially quite confusing because a call to d.now() doesn’t really have any- thing to do with the instance d. This behavior is one area where the Python object sys- tem differs from that found in other OO languages such as Smalltalk and Ruby. In those languages, class methods are strictly separate from instance methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment