Class
1  | # Define a class  | 
Class Variables
Class Variables should be the same for every instances. self is a special parameter that will always refer to the object itself. 
Restrict access to class variables: start variable name with __
1  | class Student(object):  | 
You can’t get access to private variables now:1
2
3
4
5bart = Student('Bart Simpson', 59)
bart.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'
To get and edit private variables:1
2
3
4
5
6
7
8
9
10
11class Student(object):
    ...
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
    def set_score(self, score):
        self.__score = score
Use this method, we can do a validation before setting values to class variables.
一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
不能直接访问name是因为Python解释器对外把`name变量改成了_Studentname,所以,仍然可以通过_Studentname来访问__name`变量:1
2bart._Student__name
'Bart Simpson'
Static Methods and Class Methods
Class methods provides alternative way to declare an instance of the class.
1  | class Employee:  | 
Inheritance
Method resolution order: how python look for methods and attributes.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Developer(Employee): # developer class will have all attributes and methods of Employee class
    raise_amt = 1.10
    def __init__(self, first, last, pay, prog_lang):
        super().__init__(first, last, pay) # Inheritance from parent class
        self.prog_lang = prog_lang
class Manager(Employee):
    def __init__(self, first, last, pay, employee=None):
        super().__init__(first, last, pay)
        if employees is None:
            self.employees = []
        else:
            self.employees = employees
    def add_emp(self, emp):
        if emp in self.employees:
            self.employees.append(emp)
dev_1 = Developer('Corey', 'Schafer', 50000, 'Python')
print(issubclass(Developer, Employee))
Object
1  | a = 1  | 
Explanation: https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference
Immutable Object string, tuples, numbers
If you pass a immutable object into a method, you still can’t rebind the outer reference, and you can’t even mutate the object.
Mutable Object list, dict, set
When you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to whatever, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you’re done, the outer reference will still point at the original object.
Method
There’re three types of methods in python: staticmethod, classmethod, and instancemethod
1  | def foo(x):  | 
self and cls is the binding of instance and class. 
[Difference between static method and class method] (https://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod)
For staticmethod, neither self nor cls will be implicitly passed as the first argument. They behave like plain functions except that you can call them from an instance or the class.
Class variable and instance variable
Class variable Shared by all the instance.
1  | class Test(object):  | 
1  | class Person:  | 
Polymorphism
Great Video: https://www.youtube.com/watch?v=qqYOYIVrso0
在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行
1  | b = Animal()  | 
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
1  | class Timer(object):  | 
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。