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)
    
    

     

 

posted @ 2019-08-28 15:09  WhoYoung  阅读(281)  评论(0编辑  收藏  举报