python声明类和对象_Python中的类和对象

对象是Python组织数据的形式,所有的数据都是对象(object),即某个类(Class)的instance。即便是整数,甚至整数常量这种简单的数据类型(其类为)。每个对象都有ID(identity),类型(type)和值(value)。这三者中,只有value是可以变化的,另外两个都是不可变的。

ID可以被视为对象在内存中的位置,内嵌函数id()返回了对象的ID,而is操作符则比较了两个对象的ID是否一致。type()返回了对象的类型(即所属的类Class):type(3)==int,除了常量之外(变量、类、包等)也可以用xxx.__class__得到同样结果

而类型本身也是一个对象,其类型是“type”:type(type(3))==type

"type"的所属类型也是"type":type(type(type(3)))==type

某些对象包含了其他对象(的引用),它们被称为容器(Container),比如list,tuple,dict等,这些引用是容器的值的一部分。

下文中:类、类型、type、class同义

对象、实例、object、instance同义

(1)类的层次

对象的类型(type)即其所属的类(class),这也决定了该对象所能支持的操作。内嵌函数type(object)可以得到对象所属的类。

类的层次关系:NoneType:只有一个对象,值唯一,即None

NotImplementedType:只有一个对象,值唯一,即NotImplemented

ellipsis:

numbers.Number:numbers.Integral:整数Integers:即int类型

Booleans:即bool类型

numbers.Real:即float类型

numbers.Complex:即complex类型

Sequences:有序的有限元素的集合,其元素可以用非负整数索引(即从0开始)不可变Sequences:创建之后不可修改Strings:即str类型,可通过str.encode()函数编码为bytes类型

Tuples:即tuple,元组类型

Bytes:即bytes类型,可通过bytes.decode()函数变为str类型

可变Sequences:创建之后可以修改Lists:即list类型

Byte Arrays:即bytearray类型,与bytes类型的区别在于可以修改

Set类型:无序的,有限元素的集合,可len(),可iter()Sets:可变集合,通过set()创建

Frozen Sets:不可变的集合,通过frozenset()创建,可hash()

Mappings:映射,目前只有字典一个子类字典类:即dict类型

Callable类型:可调用的类型自定义函数:用户通过def定义

实例方法:

generator函数:使用yield语句的函数

Coroutine函数:协程函数

异步generator函数:

built-in function:内嵌函数

built-in method:内嵌方法

Class:就是类,所有的类都是可调用的,返回该类的对象

class instance:类的实例,可以通过实现__call__()来变得可调用

模块:Python中的模块都是module类的对象

Custom classes:

Class instance:

I/O objects:

Internal types:Code objects:

Frame objects:

Traceback objects:

Slice objects:

Static method objects:

Class method objects:

参考:3. Data model - Python 3.9.1 documentation​docs.python.org

(2)类==对象

定义某个类的一个对象,可以用如下语句:

object = class(args...)

比如:

a = int(4)

或者

b = list([1,2,3])

由于Python中所有的类也都是对象,因此这里的class()相当于class.__call__(),即一个object的可调用函数:

a = int.__call__(4)

b = list.__call__([1,2,3])

Python中所有的类也都是对象,而这些对象的类型是type,或者说,所有类都是‘type’的实例(包括type本身也是type的实例),如此一来,定义一个新的类,相当于:

class = type(classname, superclass, attributedict)

或者

class =type.__call__(classname, superclass, attributedict)

例如:

class NewClass:

data = 1

相当于:

NewClass = type(“NewClass”, (), {‘data’:1})

相当于:

NewClass = type.__call__(“NewClass”, (), {‘data’:1})

type被是一个metaclass,即元类。

(3)metaclass

元类(metaclass)的对象是普通类,但是普通类的类可以不是‘type’,也就时说除了‘type’还可以定义其他的metaclass(通常这些metaclass的类型也是‘type’)。

定义新的metaclass,并将类的元类设置为这个新metaclass的目的,通常是为了修改创建类的对象时的过程。

在类的定义中,通过声明metaclass=MyMeta,会使得:在生成类的时候,如果有,MyMeta的__new__()和__init__()会被调用

在生成类的对象时,如果有,MyMeta类的__call__()替代type.__call__()被调用:

例如:

class Foo(metaclass=MyMeta)

会依次调用以下函数来创建Foo:

1. type.__call__():MyMeta的类型是‘type’

(1) MyMeta.__new__()

(2) MyMeta.__init__()

foo = Foo()

会依次调用如下函数来创建Foo的实例foo:

1. MyMeta.__call__()

(1) Foo.__new__()

(2) Foo.__init__()

注意混淆:

声明某个类的元类在Python3的用法是:

class Foo(metaclass=MyMeta)

在python2.7的用法则是如下:

class Foo:

__metaclass__=MyMeta

注意混淆:

注意区分“父类-子类”和“类型-对象”的关系,父类-子类能构成若干层的继承结构,但是(在不指定metaclass的情况下)所有这些类的类型都是‘type’,而子类和父类的元类可以不同,简单来说,这是两个不同维度的概念。

参考:somenzz:一文搞懂什么是Python的metaclass​zhuanlan.zhihu.comPython 元类 (MetaClass) 小教程​lotabout.me__metaclass__方法 - rookiehbboy - 博客园​www.cnblogs.com

(4)生成实例的过程

我们知道,如果类Foo的定义中有__call__函数的实现,则Foo的对象foo是可以调用的,即:

foo()

相当于调用foo所属类Foo的__call__函数:

Foo.__call__()

而当一个类Foo的对象foo生成的时候,发生的函数调用是这样的:

foo = Foo()

1. 调用Foo的所属类型的__call__:type.__call__()

(1) 调用Foo的__new__函数:Foo.__new__()

(2) 调用Foo的__init__函数:Foo.__init__()

当定义一个metaclass MyMeta的时候:

class MyMeta(type):

相当于:

MyMeta = type(“MyMeta”, ...)

1. 调用type所属类型(仍是type)的__call__:type.__call__()

(1) 调用type的__new__函数:type.__new__()

(2) 调用type的__init__函数:type.__init__()

当定义一个metaclass为MyMeta的类的时候:

class Foo(metaclass=MyMeta):

相当于:

Bar = MyMeta(“Bar”, ...)

1. 调用MyMeta所属类型(type)的__call__函数:type.__call__()

(1) 调用MyMeta的__new__函数:MyMeta.__new__()

(2) 调用MyMeta的__init__函数:MyMeta.__init__()

当生成Bar的对象bar的时候:

bar = Bar()

1. 如果Bar的所属类型MyMeta有定义__call__,则调用:MyMeta.__call__()

(1) 如果其中调用了self.__new__函数,则调用:Bar.__new__()

(2) 如果其中调用了self.__init__函数,则调用:Bar.__init__()

2. 否则,则调用type.__call__()

(1) 调用type的__new__函数:type.__new__()

(2) 调用type的__init__函数:type.__init__()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值