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
5'Bart Simpson', 59) bart = Student(
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
2 bart._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): |
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。