目录
一, 基本知识点
1, 面向过程编程
2, 面向对象编程
3, 注意
二, 类的结构
1, 类的理解
2, 代码形式
3, 类和函数的一些区别
4, 类中的数据
5, 类中的方法(基础)
三, 类的实例化
四, 类的继承
1,MRO
2, 派生, 调用, 重写
3,super()
4, 属性查找顺序
5, 广度和深度优先
五, 抽象类
1, 规则
2, 抽象类的使用
六, 类的封装功能
1,__xx 私有变量
2,property
3, 函数封装
七, 类中的方法
1, 绑定方法
实例绑定方法
类绑定方法
2, 非绑定方法
八, 类的内置方法(特殊方法, 后补)
1,item
2,...
九, 对象实例化过程(简单)
十, 元类
1, 使用 exec
2, 元类的定义
3, 类的组成要素
4, 实例化类对象
5, 通过__new__和__init__控制类对象的产生过程
6, 通过__call__控制类对象实例化对象的过程
7, 单例模式的使用
通过类的 new 方法操作
通过元类操作
十一, 几个技术问题
1,__new__方法
new 方法是生成对象的方法, 在元类中, 使用 type 元类的 new 方法生成类对象.
在类中, 使用 object 的 new 方法生成实例化对象.
new 方法应该是调用底层接口在内存中申请一个空间.
new 方法会返回一个空对象.
2,__init__方法
init 方法是对对象进行初始化的方法, 在元类中, 是对类对象进行初始化, 在类中, 是对对象进行初始化. init 方法返回值是 None.
3,super()调用时传入的都是子类对象
4, 为啥对象的绑定方法 id 不同
5, 类是装饰器
没有参数的装饰器
有参数的装饰器
6, 对象的 [] 和反射的不同
- class Student(object, metaclass=type):
- count = 0
- def __init__(self, name, age):
- self.name = name
- self.age = age
- def show_name(self):
- print('my name is:', self.name)
- class Student:
- pass
- class Student:
- a = 2
- print(Student.a) # a = 2
- Student.a = 44
- print(Student.a) # a = 44
- del Student.a
- print(Student.a) # 报错 AttributeError: type object 'Student' has no attribute 'a'
- def say(self):
- print('全局的 say 方法, hi!')
- class Student:
- a = 2
- def say(self):
- print('类里面的 say 方法, hello!')
- Student.say('something') # 类里面的 say 方法, hello!
- # 类中函数属性可以重新赋值
- Student.say = say
- Student.say('something') # 全局的 say 方法, hi!
- del Student.say
- Student.say('something') # AttributeError: type object 'Student' has no attribute 'say'
- class Student:
- school = '北京大学'
- def __init__(self, name, age):
- self.name = name
- self.age = age
- stu1 = Student('stu1', 26)
- stu2 = Student('stu2', 22)
- print(stu1) # <__main__.Student object at 0x000001F1E8E780B8>
- print(stu2) # <__main__.Student object at 0x000001F1E8E780F0>
- print(stu1.school) # 北京大学
- print(stu2.school) # 北京大学
- print(stu1.name, stu1.age) # stu1 26
- print(stu2.name, stu2.age) # stu1 26
- 1,MRO
- class Animal(object):
- pass
- class People(Animal):
- pass
- class Student(People):
- pass
- print(Student.mro())
- print(Student.__mro__) # 二者等价, 唯一的区别是上面结果是列表, 下面是元组
- # 返回结果:
- # [<class '__main__.Student'>, <class '__main__.People'>, <class '__main__.Animal'>, <class 'object'>]
- # (<class '__main__.Student'>, <class '__main__.People'>, <class '__main__.Animal'>, <class 'object'>)
- class MyMeta(type):
- a = 100
- pass
- class Animal(object):
- pass
- class Student(Animal, metaclass=MyMeta):
- pass
- print(Student.a) # a = 100
- import abc # 借助模块实现抽象类功能
- class Animal(object, metaclass=abc.ABCMeta):
- @abc.abstractmethod # 定义接口
- def run(self):
- pass
- @abc.abstractmethod
- def sleep(self):
- pass
- class People(Animal):
- def run(self):
- print('running...') # 子类必须实现, 且接口必须严格按照抽象类的定义
- def sleep(self):
- print('sleeping...')
- p = People() # 只有子类可以实例化
- p.run()
- p.sleep()
- class Student:
- def __init__(self, name):
- self.__name = name
- def __show(self):
- pass
- stu1 = Student('stu1')
- print(stu1.__dict__) # {'_Student__name': 'stu1'}
- print(stu1.name) # AttributeError: 'Student' object has no attribute 'name'
- 2,property
- class Student:
- def __init__(self, name, money):
- self.name = name
- self.__money = money # 注意, 需要使用另一个属性名, 否则会无限递归
- @property
- def money(self):
- print(f'这里可以控制 {self.name} 的 money 属性访问')
- return self.__money
- @money.setter
- def money(self, new_moeny):
- print(f'这里可以控制 {self.name} 的 money 属性设置')
- self.__money = new_moeny
- @money.deleter
- def money(self):
- print(f'这里可以控制 {self.name} 的 money 属性删除')
- raise AttributeError('此属性不可删除')
- stu1 = Student('stu1', 30000)
- print(stu1.money)
- stu1.money = 40000
- del stu1.money
- class Student:
- def __init__(self, name, money, password):
- self.name = name
- self.__money = money
- self.__password = password
- def show_money(self, password): # 对外仅仅提供这个公开接口
- print('这里可以控制访问此函数的权限')
- if password == self.__password: # 访问控制处理
- return self.__get_money()
- else:
- print('拒绝访问')
- return None
- def __get_money(self): # 内部实现细节函数, 一般无法直接访问
- return self.__money
- stu1 = Student('stu1', 30000, '123')
- print(stu1.show_money('123')) # 验证正确, 得到敏感数据
- print(stu1.show_money('abc')) # 没有得到敏感数据
- code = """
- a = 2
- global b
- b = 3
- def show():
- print('hello')
- """
- g_dic = {}
- l_dic = {}
- exec(code, g_dic, l_dic)
- print(g_dic) # b 的定义
- print(l_dic) # a 和 show 函数的定义
- class MyMeta(type):
- def __new__(cls, class_name, class_bases, class_dic):
- print('元类, cls is:', cls.__name__)
- print('现在准备创建类对象:', class_name)
- return super().__new__(cls, class_name, class_bases, class_dic)
- def __init__(self, class_name, class_bases, class_dic):
- print('选择要对类对象初始化', self.__name__)
- self.class_name = class_name
- self.class_bases = class_bases
- self.class_dic = class_dic
- self.a = 2
- class Student(object, metaclass=MyMeta):
- pass
- print(Student.a) # 2
- class MyMeta(type):
- def __call__(self, *args, **kwargs):
- print('此类正在执行 call', self.__name__)
- obj = object.__new__(self)
- self.__init__(obj, *args, **kwargs)
- return obj
- class Student(object, metaclass=MyMeta):
- pass
- stu1 = Student()
- print(stu1)
- class Student:
- __instance = None
- def __new__(cls, *args, **kwargs):
- if cls.__instance is None:
- obj = object.__new__(cls)
- cls.__init__(obj, *args, **kwargs)
- cls.__instance = obj
- return cls.__instance
- stu1 = Student()
- stu2 = Student()
- print(stu1 is stu2) # True
- class MyMeta(type):
- def __init__(self, *args, **kwargs):
- self.instance = None
- def __call__(self, *args, **kwargs):
- if self.instance is None:
- obj = object.__new__(self)
- self.__init__(obj, *args, **kwargs)
- self.instance = obj
- return self.instance
- class Student(object, metaclass=MyMeta):
- pass
- stu1 = Student()
- stu2 = Student()
- print(stu1 is stu2)
- class Animal:
- def f(self):
- print('这里是 animal')
- print('self 是:', self)
- class People(Animal):
- def f(self):
- print('这里是 people')
- super().f()
- class Student(People):
- def f(self):
- print('这里是 student')
- super().f()
- stu1 = Student()
- print(stu1) # 和 stu1.f()中的对象是同一个
- stu1.f()
- class Student:
- def eat(self):
- print('eating...')
- stu1 = Student()
- stu2 = Student()
- print(stu1.eat) # bound method 0x000002C94A04C9E8
- print(stu2.eat) # bound method 0x000002C94A04CA20
- class Student:
- def eat(self):
- print('eating...')
- stu1 = Student() # __main__.Student object 0x00000192233FC9E8
- print(stu1)
- bound_func = stu1.eat
- print(bound_func.__self__) # __main__.Student object 0x00000192233FC9E8
- print(bound_func.__func__) # function Student.eat at 0x00000192233F9488
- class Wrapper:
- def __init__(self, func):
- self.func = func
- def __call__(self, *args, **kw):
- print('start')
- self.func(*args, **kw)
- print('end')
- @Wrapper
- def show():
- print('这里是 show 函数')
- show()
- # start
- # 这里是 show 函数
- # end
- class Wrapper:
- def __init__(self, key):
- self.key = key
- def __call__(self, func):
- self.func = func
- def inner(*args, **kw):
- print('start')
- self.func(*args, **kw)
- print('end')
- return inner
- @Wrapper('key')
- def show():
- print('这里是 show 函数')
- show()
- # start
- # 这里是 show 函数
- # end
- class Student:
- a = 2
- print(getattr(Student, 'a')) # 2,getattr 是获取对象的属性
- dic = {
- 'a': 100,
- }
- print(getattr(dic, 'a')) # 报错, 字典中的 key 需要使用 dic['a']访问
来源: https://www.cnblogs.com/zzzlw/p/9250939.html