一、阶级关系
1. Programs are composed of modules.
2. Modules contain statements.
3. Statements contain expressions.
4. Expressions create and process objects.
二、教学大纲
-
<Think Python>
-
菜鸟教程
Goto: http://www.runoob.com/python3/python3-class.html
参考资源:廖雪峰,Python面向对象编程
参考资源:廖雪峰,Python面向对象高级编程
参考资源:错误、调试和测试
-
面向对象的三大特点
数据封装(Encapsulation )、继承(inheritance )和多态(polymorphism)。
Encapsulation
类的定义
-
构造方法
赋值的的过程,就自动完成了类内的变量定义。
#!/usr/bin/python3 class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart
x = Complex(3.0, -4.5) print(x.r, x.i) # 输出结果:3.0 -4.5
self 参数
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的 第一个参数名称:self
注意:self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定使用 self。
self 记录了 “类的地址”,“类的属性” 等各种类的属性。
class Test: def prt(self): print(self) # address print(self.__class__) # name t = Test() t.prt()
执行结果:
<__main__.Test instance at 0x100771878> __main__.Test
权限控制
-
“私有” 属性 & 方法
加上 “双下划线” 定义属性为私有属性。
#!/usr/bin/python3 class people: name = '' age = 0 __weight = 0 def __init__(self, n, a, w): self.name = n self.age = a self.__weight= w def speak(self): print("weight is {}".format(self.__weight)) def __talk(self): print("age is {}".format(self.age)) p = people('runoob', 10, 30) ##################### # private attribute ##################### print(p.name) # print(p.__weight) # <-- this is err case. print(p._people__weight) ##################### # private function ##################### p.speak() # p.__talk() # <-- this is err case. p._people__talk()
“私有化” 原理
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
>>> bart._Student__name 'Bart Simpson'
但是强烈建议你不要这么干,因为 “不同版本的Python解释器可能会把__name改成不同的变量名”。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
-
限制滥用 “对象成员”
__slot__关键字
由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。
注意:使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用。
class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 >>> s = Student() # 创建新的实例 >>> s.name = 'Michael' # 绑定属性'name' >>> s.age = 25 # 绑定属性'age' >>> s.score = 99 # <---- 绑定属性'score' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'score'
为何用?内存环保
Ref: 10. __slots__ Magic
动态语言意味着“浪费空间”换取“灵活性”。显然,减少不必要的灵活性可以 reduce memory of RAM。添加__slots__后带来的内存环保效果如下:
The code will reduce the burden on your RAM. Some people have seen almost 40% to 50% reduction in RAM usage by using this technique.
class MyClass(object): __slots__ = ['name', 'identifier'] def __init__(self, name, identifier): self.name = name self.identifier = identifier self.set_up() # ...
-
成员变量 Set & Get
过去的策略
分别定义set, get函数操作。
装饰器策略
将函数当做属性来使用:
(a) 只有@property表示只读。
(b) 同时有@property和@x.setter表示可读可写。
(c) 同时有@property和@x.setter和@x.deleter表示可读可写可删除。
class student(object): def __init__(self,id): self.__id=id @property # 只读 def score(self): return self._score @score.setter # 只写 def score(self, value): # 设置前的checker if not isinstance(value,int): raise ValueError('score must be an integer!') if value<0 or value>100: raise ValueError('score must between 0 and 100') # 开始设置 self._score=value @property # 只读 def get_id(self): return self.__id s=student('123456') s.score=100 # 写 print(s.score) # 读 print(s.__dict__) print (s.get_id) # 只读 #s.get_id=456 #只能读,不可写: AttributeError: can't set attribute