python 如何循环创建类名,并创建对象使用?

在开始本章之前,我们先明确一个关系,对象与类的关系是实例关系而不是继承关系

对象与类的关系,类似于从一个模板(类)中复制粘贴(实例化)出一个新物体(对象) ,

只要对象被创建出来后就不会直接受类的影响

继承的关系,是一种单向链关系,父类会直接影响到子类,而子类不会直接影响到父类

super函数的官方文档:

  • (我们先称用关键字 class 创建的类为“用户自定义类”)

如果我们尝试查询一个用python内置函数type( )去查询一个“用户自定义类”

也就意味着,“用户自定义类”本质上也是type类的一个实例对象而已。

因为“用户自定义类”的本质还是一个对象,所以类也可以像对象一样进行赋值

由于“用户自定义类”也只是对象,

因此我们可以像创建对象一样,在程序运行时动态的创建类

(例如在函数中,for循环中,等各种地方使用class关键字创建类)

__init__( )也可以被称为构造方法(前面提过了)

作用:初始化一个新建对象

何时调用:当你在创建一个新的实例对象时

注意:虽然__init__( )参与初始化对象的过程,但是__init__( )不是创建对象的方法

而__init__这个方法会对创建出来的实例对象进行初始化(只要创建一个新的对象,就会被运行一次)

(例如:添加新的属性和方法等初始化工作)

因此 self.a 只存在于 由Name类创建的对象obj中,而不存在于Name类中

通过dir( )方法查询即可

作用:初始化一个新建的类,并返回一个类type的实例即“用户自定义类”

何时调用:当你在创建一个新的类时(事实上是每次创建对象时都会运行的一次该方法)

注意:虽然__new__( )参与初始化“用户自定义类”和创建新实例对象的过程,但是__new__( )不是创建类的方法

提示:“用户自定义类”是type类的实例对象,由此可知“用户自定义类”是由type类中的__new__( )实例化后生成的

而__new__这个方法会在类创建之初对类进行初始化,(只要创建一次新的类就会被运行一次)

(例如:添加新的属性和方法等初始化工作)

因为cls.val是在类创建时添加进类的,

所以无论是由Name类创建的对象obj,还是Name类本身,都会有cls.val这个属性

__new__会在每次创建实例的时候对类进行初始化,并完成创建实例的任务

如果尝试在__new__方法中修改属性,会对类造成影响,

  • (也会对已创建的实例对象造成影响)

因为要先有类,并创建出对象后,才能对对象进行初始化

(self 和 cls 都是自定义的名称,但是按照规范,默认写成self和cls,这样看范例也方便)

cls通常在类中,用来表示类自己

self通常在对象中,用来表示对象自己

__call__这个方法可以用来重载括号( )这个运算符

这个方法一般在创建对象时不常用,但在创建“用户自定义类”时,和调用函数方法时会被调用

  • (“用户自定义类”也是一个实例<class 'type'>的实例对象)

无法被(类)自己直接使用,只能由被(类)创建出来的实例对象使用

  • (具体原因还是请参考手册,这只是我测试出来的结果)

只有(类)进行实例出来的对象,才能通过重载的方式去调用__call__

类本身无法直接使用__call__

“用户自定义类”本身也是一个实例对象,是<class 'type'>的实例对象,里面也有__call__,

当我们创建一个“用户自定义类”时,本质上是创建了一个type类的实例

细心的朋友会发现,当“用户自定义类”要创建实例对象时,

必须在“用户自定义类”的名字后面跟一个括号()

其实本质上 就是调用了type类实例化出来的 对象“用户自定义类”中的__call__方法

(这个__call__的作用是用来帮助“用户自定义类”生成实例的)

(注意:在“用户自定义类”中定义的__call__,和这个__call__几乎毫无关联)

  • 而实例对象的__call__的直接关联的“用户自定义类”中定义的__call__

(在生成实例前是上面那个__call__,生成实例后就被替换掉了)

除了使用 calss来创建类以外,其实还可以通过下面这个方法来生成一个类

如果细心的同学会发现,创建“用户自定义类”的实例,就是在类名后面加个括号

由此可知创建实例就是调用__call__

但是__call__方法本身并不能生成实例,他只是重载的运算符()

真正用来创建实例的方法是__new__方法,__new__能先初始化类后,返回实例

但上面我们在创建实例对象时,我们只调用了__call__。

这样在调用__call__时就能返回实例了

(注:这个call是由type内定义的,所以没有写在class里)

同时我们知道,在__new__运行完成之后,会使用__init__进行实例化操作

(这部分请自动忽略,我写着玩的)

(这个词是非官方的词,所以别去网上搜了,找不到的)

(伪类:仿类工作原理的对象)

根据【对象的生成历程】可以大致了解了类是怎么生成对象的

  • “用户自定义类”创建实例化对象,

本质上是通过调用“用户自定义类”(type的对象)中的__call__( )实现的。

最后将__new__的返回值(即实例)作为__call__的反回值

根据上述特点,我们可以做一个伪类(可以生成对象的对象)

通过最后的修改伪类创建的属性,发现完全可以各改各的,说明成功创建了一个能生成对象的对象(伪类)

当然这也是类的基本原理应该也差不多了

只不过调用type这个过程通过重载隐藏掉了而已,

取而代之的是熟悉的class定义方式

所有的“用户自定义类”都是它的实例化对象

所有的元类(MetaClass)都是以他为基础的派生类

是继承自type类的类,具有和type相似的属性,元类的实例化对象就是类

元类也被称为超类(从类的角度上看,称为类模板应该会更好理解)

并重新重载class方法实现的

约定习惯:为了方便识别类与元类,通常元类名是以 Meta 或者 Metaclass 结尾

何时被调用: 用元类创建实例类时

何时被调用:  当实例类创建对象时被调用

元类中定义的方法和属性,只能被实例类调用,不能被实例类创建的对象直接调用

(在实例类中,与私有属性类似私有部分)

定义元类后,type类的 type( )函数会被重新重载

通过关键字class 就可以实现创建类了

与平常的类创建方法基本相同,括号内依旧写基类名,

只是最后的一个参数必须是(metaclass = 元类名)

name:是字符串(用来储存实例类的名字)

bases:是元组(用来储存基类名字)

dic:是字典(用来储存属性和方法)

由于我不是很需要使用元类,所有不继续探索下去了

如果由兴趣,可以去找找下面这两个关键词

compile(正则表达式) - 编译正则表达式,创建正则表达式对象

1)fullmatch(正则表达式, 字符串) - 让整个字符串和正则表达式进行匹配

2)match(正则表达式, 字符串) - 匹配字符串开头

如果匹配不到结果是None,如果匹配成功了结果是匹配对象

设置同时忽略大小写单行匹配

1)获取匹配到的字符串
匹配对象.group() - 获取整个正则表达式匹配到结果

匹配对象.group(分组号) - 获取正则表达式中指定的分组匹配到的结果(分组号从1开始)

2)获取匹配到的子串的范围

1)search(正则表达式,字符串) - 在字符串中查找第一个能和正则表达式匹配的子串。如果找到了返回匹配对象,找不到返回None

  1. findall(正则表达式,字符串) - 获取字符串中所有满足正则表达式的子串。返回一个列表,列表中的元素是字符串

  2. finditer(正则表达式,字符串) - 获取字符串中所有满足正则表达式的子串。返回一个迭代器,迭代器中的元素是匹配对象

findall正则中如果有分组,只获取分组匹配到的内容

split(正则表达式, 字符串) - 将字符串中能和正则表达式匹配的子串作为切割点,对字符串进行切割。返回值是列表,列表中的元素是字符串
split(正则表达式, 字符串, 次数) - 指定切割次数

sub(正则表达式, 字符串1, 字符串2) - 将字符串2中能和正则表达式匹配的子串全部替换成字符串1
sub(正则表达式, 字符串1, 字符串2, 次数) - 限制替换次数

面向过程编程(穷人的思想):一遇到问题马上想到的是怎么写代码把这个功能实现(逻辑)

函数式编程(小资的思想):一遇到问题马上想到有没有一个函数已经把这个功能实现了,如果有就拿过来用,没有就定义一个有这个功能的函数(函数)

面向对象编程(富豪的思想):一遇到问题马上想到有没有一个类中有这个方法能够把这个功能实现,如果没有就创建这个类(类和对象)

4.1 什么是类、什么是对象

类就是拥有相同属性和相同功能的对象的集合(抽象)
对象就是类的实例(具体)

如果人是类, 余婷就是对象,骆老师是另一个对象
如果杯子是类,我桌上的这个杯子就是对象

4.2 定义类(说清楚共同属性和功能是哪些)

类的内容(包含属性和方法)

类名 - 程序员自己命名
要求:标识符,不能是关键字
规范:驼峰式命名,并且首字母大写;见名知义;不适用系统的函数名、类名、模块名
类的说明文档 - 用""""""引起来的说明性文字,主要说清楚类提供了哪些属性和哪些功能
类的内容 - 主要包含属性和方法(定义在类中的函数叫方法)

4.3 定义对象(创建对象)

类名 - 是已经定义好的类的类名

4.1 方法(定义在类中函数)

类中的方法分为三种:对象方法、类方法、静态方法

怎么定义:直接定义在类中函数就是对象方法
特点:自带参数self(self在通过对象调用的时候不用传参, 系统会自动将当前对象传给self),谁调用指向谁
怎么调用:用对象去调用(对象.方法名())

特点:自带参数cls(cls在通过类调用的时候不用传参,系统会自动将当前类传给cls)
怎么调用:用类调用(类.方法名())

4)对象方法、类方法和静态方法怎么选:
如果实现函数的功能需要用到对象的属性,就选对象方法

\# 用对象调用对象方法 \# 用类调用静态方法 \# 从本质上讲,类中的所有的方法都可以用对象和类调用,但是不能这么做 Dog.eat(12) # 如果用类调用对象方法,self就会变成普通的参数,没有存在的价值 dog1.count() # 用对象调用类方法的时候cls指向的还是类(不会指向对象)

构造方法: 函数名和类名是一样的,用来创建对象的方法就是构造方法(Python中的构造方法,在定义类的时候系统已经自动创建好了)

init方法又叫初始化方法,用来在创建对象的是对对象进行初始化操作的。
当我们通过类创建对象的时候,系统会自动调用init方法来对象创建出来的对象进行初始化。

调用构造方法创建对象的时候需不需要参数,需要几个,看被自动调用的init

对象 = 申请空间创建对象

7.1 属性: 对象属性和类属性

对象属性: 对象属性的值会因为对象不同而不一样
c.通过 对象.属性名 的方式使用属性

我要回帖

更多关于 python如何动态创建一个类 的文章

 

随机推荐