(四)python语法之面向对象

1.类和实例

class Student(object):
    score = 100  # 类的属性
    __math = 10  # 类的私有属性
    
    # 限制实例能添加的属性
    __slots__ = ['name', '_age', '__sex'] 
    
    def __init__(self, name, age, sex):
        self.name = name 
        self._age = age   # 约定的私有属性
        self.__sex = sex  # 私有属性

    # 约定的私有方法
    def _getage(self):     
        print("age: ", self._age)      

    # 私有方法
    def __getsex(self):    
        print('sex: ', self.__sex)

    # 静态方法
    @staticmethod 
    def func1():
        print('staticmethod'); 

    # 类方法
    @classmethod  
    def func2(cls, name, age, sex):
        print(cls.score)            
        cls(name, age, sex).func1() 
      
s = Student('aya', 18, 'girl')

# 属性访问
print(s.score, s._Student__math)
print(s.name, s._age, s._Student__sex)

# 实例方法调用
s._getage()
s._Student__getsex()

# 静态方法调用
s.func1()
Student.func1()

# 类方法调用
Student.func2('aya', 18, 'girl')

print(Student.__dict__)   # 类的属性字典
print(Student.__doc__)    # 类的文档
print(Student.__name__)   # 类名
print(Student.__module__) # 类定义所在模块
print(Student.__bases__)  # 类的所有父类

2.property

# property装饰器将方法变成属性

class Student(object):
    def __init__(self, birth):
        self._birth = birth
    
    # birth是可读写属性
    @property                     
    def birth(self):
        return self._birth
    
    @birth.setter
    def birth(self, value):
        self._birth = value    
    
    @birth.deleter
    def birth(self):
        print("删除属性")
        del self._birth
        
    # age是只读属性
    @property                     
    def age(self):
        return 2020 - self._birth  

s = Student(2000)
print(s.birth) # 2000
s.birth = 2002
print(s.birth) # 2002
print(s.age)   # 18

del s.birth

3.继承

单继承

class Student(object):
    def __init__(self, name):
        self.name = name
        
    def get_name(self):
        print("Student", self.name)      
        
class Girl(Student):
    def __init__(self, name):   
        super().__init__(name)
        self.sex = 'Girl'

    def get_name(self):
        super().get_name()
        print(self.sex, self.name)

g = Girl('Alice')
g.get_name()
# Student Alice
# Girl Alice

多继承

class Base:
    def __init__(self):
        print('Base.__init__')

class A(Base):
    def __init__(self):
        super().__init__()
        print('A.__init__')

class B(Base):
    def __init__(self):
        super().__init__()
        print('B.__init__')

class C(A,B):
    def __init__(self):
        super().__init__()
        print('C.__init__')

c = C()
# Base.__init__
# B.__init__
# A.__init__
# C.__init__

C.__mro__ # 所有基类的线性顺序表
# (__main__.C, __main__.A, __main__.B, __main__.Base, object)

4.运算符重载

常用运算符

class Vector(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    # print()时显示的内容
    def __str__(self):
        return 'Vector(%r, %r)' % (self.x, self.y)
    __repr__ = __str__

    # 重载加号运算符
    # 类似的:sub  mul  div  mod  pow
    def __add__(self, other):
        return Vector(self.x+other.x, self.y+other.y)
    
    # 直接调用实例自身
    def __call__(self):
        print('Called by myself!')
    
v1 = Vector(1, 1)
print(v1)      # Vector(1, 1)

v2 = Vector(2, 2)
print(v1 + v2) # Vector(3, 3)

v2()           # Called by myself!

下标运算符

# 自定义一个只能存放int类型的list

class IntList(object):
    def __init__(self, *args):
        if all(map(lambda x:isinstance(x, int), args)):
            self._list = list(args)
        else:
            print("所有传入的参数必须是整数!")
            
    def __getitem__(self, index):
        return self._list[index]
    
    def __setitem__(self, index, value):
        self._list[index] = value
        
    def __delitem__(self, index):
        del self._list[index]
        
    def __len__(self):
        print("调用__len__方法")
        return len(self._list)

l = IntList(1,2,3,4,5)
print(len(l))
# 调用__len__方法
# 5

print(l[0]) # 1

l[0] = -1
print(l[0]) # -1

del l[0]
print(l[0]) # 2

5.元类

#1 type()动态创建类
def myfunc(self, name='Tom'):
     print('Hello, %s!' % self.name)

# 参数分别为:class名称、继承的父类集合、方法名称与函数绑定       
Student = type('Student', (object,), dict(name='Jack', func=myfunc)) 
s = Student()
s.func()  # Hello, Jack!

#2 metaclass元类
class ListMetaclass(type): 
    def __new__(cls, name, bases, attrs):
        # 为类动态添加属性
        attrs['doc'] = 'A metaclass!'
        # 为类动态添加方法
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)

# 使用ListMetaclass来定制类
class MyList(list, metaclass=ListMetaclass):
    pass

L = MyList()
L.add(1)  
print(L)     # [1]
print(L.doc) # A metaclass!

6.单例模式

class Singleton(object):
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = object.__new__(cls)
        return Singleton._instance

obj1 = Singleton()
obj2 = Singleton()
print(id(obj1) == id(obj2)) # True
posted @ 2020-08-20 16:45  qxcheng  阅读(104)  评论(0编辑  收藏  举报