Python学习笔记(四)
Python 面向对象编程
学习目标:
1、类及类的继承 (重点)
2、析构方法和内存管理
3、辖域(Scoping)规则和命名空间(Namespace)
4、特定方法属性(Special Method Attribute) (重点)
————————————————————————————————————————————
在类中定义方法(一)
实例方法
- 使用self在方法中引用实例自身
- 使用实例对象时可以省略self
class Shape :
def __init__(self, x=0, y=0) :
self.x = x
self.y = y
def move(self, deltaX, deltaY) :
self.x += deltaX
self.y += deltaY
shape = Shape()
shape.move(2,3)
print(shape.x)
print(shape.y)
Shape(shape,2,3) #语法没问题,但不推荐使用
在类中定义方法(二)
静态方法
- 使用内置装饰器:staticmethod装饰
class Math:
@staticmethod
def factorial(n):
if n <= 2: return n
return Math.factorial(n-1)*n
result=Math.factorial(100)
在类中定义方法(三)
类方法classmethod
- 与静态方法的区别:1、将类本身作为对象进行操作的方法 2、使用装饰器@classmethod 3、方法的一个参数为cls,表示这个类本身
Tips:不要交叉调用,即不要用类名调用实例方法,不要用实例调用类的方法,会造成变量的错用。
动态修改类中的方法
给类添加新的方法
Circle.fn = lambda self, x : x*2*3.14
aCircle.fn(100)
修改类中的方法
Shape.move = lambda self, x, y : x+y
s.move(10, 10) # move is changed
删除类中的方法
del Shape.move
s.move(10, 10) # move does not exis
Tips: 与JAVA不同,Python的实例变量必须定义在实例方法或构造方法中或在实例对象后创建。
在类中定义变量(一)
实例变量,在实例方法上声明或在实例对象上声明。
#实例变量
class Shape(object) :
def __init__(self, x=0, y=0) :
self.x = x # 在构造函数中声明
self.y = y
def move(self, deltaX, deltaY) :
self.x += deltaX
self.y += deltaY
x = Shape()
x.x=100 # access instance variables
注:在实例创建后给实例添加新的实例变量
x = Shape()
x.newVar=100
del x.newVar
在类中定义变量(三)
在类中直接定义的变量为类变量,相当于静态变量 使用类名来调用类变量
class Circle:
pi = 3.1415926 # this is not instance variable
def func():
Circle.pi2 = 6.2831852
继承
- 语法与Java类似
- 可以多继承,遵循MRO规则(类似先序遍历,但不是)
- 子类定义构造方法后,父类的构造方法需要显示调用
class Shape(object) :
def __init__(self):
self.x = 0
self.y = 0
def move(self, deltaX, deltaY) :
self.x += deltaX
self.y += deltaY
class Square(Shape) :
pass
命名空间
-
命名空间
- 命名空间是名字和对象的映射
- 各个命名空间相互独立,彼此间没有任何关系
- 命名空间通常是使用字典实现的
-
作用域
- 在作用域中,可直接访问当前命名空间中的变量和方法
-
在对象和类中调用变量/方法的顺序
-
对象的作用域
-
在类中搜索
- 当前类
- 父类
-
同名变量优先于方法
-
特定方法属性
通过重写特定的方法名,实现与特定操作符的关联(如实现了contains方法,即可用于in 的判断)
-
类转字符串: __str__(self):
-
类的比较: 定义后即可使用比较运算符
__lt__(self,other) __le__() __gt__() __ge__() __eq__() __ne__()
-
对象的函数调用,实现obj()的语法
__call__(self,*args) #对象作为函数调用,也就是直接用对象名调用该对象命名空间中的__call__方法(语法糖)
-
模拟集合,实现 key in obj的语法
class A : def __len__(self): return 0 def __contains__(self, key): return True a = A() len(a) 5 in a
-
模拟字典,实现obj["key"]的语法
class A : def __getitem__(self, key): return None def __setitem__(self, key, value): pass def __delitem__(self, key): pass def __missing__(self, key): # called by __getitem__ pass a = A() a[2]=a[1] del a[1]
-
模拟迭代器语法
class A : def __next__(self): if 'invoked' not in vars(self): self.invoked=0 self.invoked+=1 if self.invoked >3: raise StopIteration return 'Next!' def __iter__(self): return self def __reversed__(self): return self a = A() for item in a: print(item)