类、对象、父类、元类

python中一切皆对象

1. 名词解释

  1. 类: 类是一个抽象的概念,是一系列对象中相似特征与技能的结合体,不存在某一个对应的实体
  2. 对象:是类实例化的结果, 是一个实际存在的事物,通过对象可以找到一个固定的个体
  3. 父类: 类存在继承的特性, 类可以继承父类, 并继承其中的方法与属性, python3中都是新式类,不写明时都是继承自 object基类
  4. 元类: python中一切皆对象, 类本身也是对象, 元类就是用来生成类的类

2. 名称空间的访问顺序

前提:我们平时调用方法与属性时, 通常是通过 类生成的对象 来调用的

  1. 普通对象的名称空间 -> 类的名称空间 -> 根据mro列表查找父类的名称空间

上方需要说明的是:

  • 我们平时会根据类生成对象, 然后通过对象来调用方法与属性
  • 此时我们首先会访问对象的名称空间, 然后访问类的名称空间, 然后访问父类的名称空间
  • 此过程并不会访问元类的名称空间, 因为对象只能向上访问到类及父类的名称空间

然而

  • 我们会想,不是会访问类的名称空间嘛? 元类也是类, 为什么不会访问到呢?
  • 那是因为: 元类是类的类, 而不是对象的类, 只有我们通过 【类.方法】 访问方法时, 才会先访问类自己的名称空间, 然后再访问元类的名称空间, 因为元类 是 类的类

3. __init__, __new__, __call__

前提: 类实例化对象时分为两步:1. 通过类的__new__方法生成一个空的对象 2. 通过类的__init__方法来初始化对象

  1. __init__: 是用来对象初始化的, 通过__init__中的方法,可以初始化对象中独特的属性, 生成对象自己的名称空间
  2. __new__: 是用来生成空的对象的, 我们听其他语言说的new一个新对象可以辅助我们理解
1. 在生成对象时, 首先会调用 类的 __new__方法, 生成一个空的对象
class TestClass:   ## 基础的单例模式
    obj = None
    def __new__(cls, *args. **kwargs):
        if cls.obj:
            return cls.obj
        else:
            cls.obj = super().__new__(cls, *args, **kwargs)
            return cls.obj
a = TestClass()
b = TestClass()
print(a)  ## <__main__.TestClass object at 0x000001F2BC04ACD0>
print(b)  ## <__main__.TestClass object at 0x000001F2BC04ACD0>
2. 然后调用对象的 __init__方法, 进行对象的初始化
  1. __call__ : 此方法用来表示对象是否可执行, 对象会调用类的__call__ 方法, 如果类存在此方法, 就可以调用, 不存在就不可以调用, 决定类是否可以被调用的方法是元类的__call__方法
class TestClass:
    def __init__(self, name):
        self.name = name 
    def __call__(self):
        return self.name
lee = TestClass('lee')  # 不会打印
andy = TestClass('andy')  # 不会打印
lee()  # lee
andy()  # andy

4. 自定义元类

我们如果想要控制类的生成, 可以自定义元类

class MetaClass(type):   # 继承自元类
    def __init__(cls, class_name, bases, dict):  # 此处无法修改dict内的值
        cls.name = 'andy'  # 此方式可以为类增加属性
        if not class_name.istitle():
            super().__init__(class_name, bases, dict)
        else:
            raise valueError('class name is not valid')
    def __new__(cls, class_name, bases, dict):
        dict['__author__'] = 'lee'  # 为类增加属性
        return super().__new__(cls, class_name, bases, dict)
其中:
 - class_name, bases, dict 是三个固定不必须要传入的参数
 - class_name: 类的名字
 - bases: 类的父类们
 - dict: 类的名称空间 


class FromMetaClass(metaclass=MetaClass):
    def __init__(self):
        pass
print(FromMetaClass.__dict__)  
# {'__module__': '__main__',
# '__init__': ,
# '__author__': 'lee',
# '__dict__': , 
#'__weakref__': , 
#'__doc__': None, 
#'name': 'andy'}

你可能感兴趣的:(类、对象、父类、元类)