Python学习笔记八 面向对象高级编程(二)元类

参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

在廖老师的学习网站里“使用元类”这部分还是把我给看晕了...网上搜到一篇感觉讲的相对易懂一些,贴出链接:两句话掌握 Python 最难知识点——元类——以此文作为这篇笔记的源本。

“道生一,一生二,二生三,三生万物”

1、在Python世界中,“type”即为道,即是生出各种类、对象、变量等等一切的源头。

2、一——即是metaclass(元类,也叫类生成器)

3、二——即是各种常规的类(class)

4、三——即是实例(instance)

5、万物——即是实例的各种属性和方法

#创建一个Student类,这个类即为“二”
class Student():
def printinfo(self):
        print("It is a instance of Student!")

#创建Student的实例s,即为“二生三”
s=Student()

#使用实例的属性、方法,即为“三生万物”
s.printinfo()

这段代码提现从二到万物的过程,那么对于Student类这个“二”从何而来呢?

我们看到的定义类的class Student()...这些代码,实际上如下:

def fn(self):
    print("It is a instance of Student!")
Student=type(‘Student‘,(object,),dict(printinfo=fn))

注意到这里,Student类是通过type()方法生成的,其中有三个参数,分别为设置类的名字,使用一个元组明确该类的父类,使用一个字典给出这个类的方法。

type是“道”,可以先通过type生成元类,再由元类生成各种类。

“元类”

一般来说,元类都被命名为后缀Metaclass。

先看一个定义元类的例子:假设需要一个可以自动打招呼的元类,它里面的类方法有时需要say_Hello,有时需要say_Hi,有时又需要say_Sayolala,有时需要say_Nihao。

class SayMetaclass(type):  #注意到元类均继承自type
    def __new__(cls,name,bases,attrs):
        attrs[‘say_‘+name]=lambda self,value,saying=name:print(saying+‘,‘+value+‘!‘)
        return type.__new__(cls,name,bases,attrs)

注意:

1、元类都是由"type"衍生出来的,所以父类必须传入type。

2、元类的操作都是通过__new__()完成,第一个参数是将创建的类的对象(是否基本类似于self?),后面三个参数分别为:类名、父类、属性/方法。

具体看这个代码:

attrs[‘say_‘+name]=lambda self,value,saying=name:print(saying+‘,‘+value+‘!‘)

这里是给每个类定义一个”‘say_‘+类名”的属性,具体在这里是一个方法,通过lambda定义的方法,这个方法有三个参数,第一个self,是因为是类的方法,所以必须第一个为self,第二个是常规的位置参数value,需要使用者自己传入,第三个是一个默认参数,默认为类名。

通过这个元类继续生出各个类:

class SayMetaclass(type):  #注意到元类均继承自type
    def __new__(cls,name,bases,attrs):
        attrs[‘say_‘+name]=lambda self,value,saying=name:print(saying+‘,‘+value+‘!‘)
        return type.__new__(cls,name,bases,attrs)

#通过SayMetaclass创建一个Hello类
#注意用法,参数除了第一个父类外,必须使用metaclass=标明该类使用的元类
#因为这里类名是Hello
#所以这个Hello类拥有一个“say_Hello”的属性
#而这个属性又是一个方法,即等效于下面代码的方法:
‘‘‘
def say_Hello(self,value,saying=‘Hello‘):
        print(saying+‘,‘+value+‘!‘)
‘‘‘
class Hello(object,metaclass=SayMetaclass):
    pass
Hello().say_Hello(‘World‘)  

#基于元类继续创建新的类
class Nihao(object,metaclass=SayMetaclass):
    pass
Nihao().say_Nihao(‘China‘)
Nihao().say_Nihao(‘China‘,saying=‘Very Great‘) 

#基于元类继续创建新的类
class Sayolala(object,metaclass=SayMetaclass):
    pass
Sayolala().say_Sayolala(‘Japan‘)  

输出如下:

Hello,World!
Nihao,China!
Very Great,China!
Sayolala,Japan!

原文地址:https://www.cnblogs.com/tsembrace/p/8684545.html

时间: 2024-12-17 00:23:01

Python学习笔记八 面向对象高级编程(二)元类的相关文章

Python学习笔记八 面向对象高级编程(一)

参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 一.使用__slots__ 正常情况下,当定义了一个类之后,我们可以给这个类的实例绑定任何属性,这就是动态语言的优势: class Student(object): def __init__(self,name,age): self.name=name self.age=age bob=Student('Bob

python学习笔记(七) - 面向对象高级编程

一. 为类动态添加属性和方法: 1. 动态给一个实例添加属性和方法: 给一个实例绑定的方法,对另一个实例是不起作用的. class Student(object): pass s = Student() s.name = 'Michael' # 动态给实例绑定一个属性 print s.name def set_age(self, age): # 定义一个函数作为实例方法 self.age = age from types import MethodType s.set_age = MethodT

Python学习笔记捌——面向对象高级编程

__slots__特殊变量的使用: 由于Python是动态语言,允许先编写类,然后在创建实例的时候添加属性或者方法:而__slots__特殊变量就是,限制往类里添加属性的: 在创建类的时候,使用__slots__ =('name','age'),就是在创建实例时候,只允许添加绑定name和age两个属性:注意!__slots__只对当前类有效,不会作用于子类: @property装饰器:为了实现数据的封装,不把属性暴露在外面,所以如果想访问实例内部属性的话,就需要使用get和set方法,但是这样

Python笔记7#面向对象高级编程二

▲定制类 Python中有许多类似__slots__这样有特殊用途的函数,可以帮助我们定制类. 官方文档链接:https://docs.python.org/3.4/reference/datamodel.html#special-method-names 1)__str__和__repr__ 示例代码如下: >>> class Student(object): ... def __init__(self, name): ... self.name = name ... >>

【Python学习之七】面向对象高级编程——__slots__的使用

1.Python中的属性和方法的绑定 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法. (1)首先,定义一个class:  class Student(object):  pass (2)然后,给实例绑定属性: >>> s = Student() >>> s.name = 'Michael' # 动态给实例绑定一个属性 >>> print(s.name) Michael (3)或者,给实例绑定一

python学习笔记12-python面向对象

python学习笔记12-python面向对象 python一切皆对象 一.基本概念 1.面向对象和面向过程 面向对象编程:C++,Java,Python 面向过程编程:函数式编程,C程序等 2.类和对象 类:是对事物的抽象,比如:人类,球类 对象:是类的一个实例,比如:足球,篮球,对象就是对类的实例化 属性:五官,眼,鼻子,理解为一个变量,静态属性 方法:对人来说,吃穿住行,理解为一个函数,动态方法 实例说明:球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来 3.为什么要使

python学习笔记八——正则表达式

1.元字符 []-常用来指定一个字符集:[abc];[a-z] -元字符在字符集中不起作用:[akm$] -补集匹配不在区间范围内的字符:[^5] ^-匹配行首 $-匹配行尾 \-后可加不同字符以表示不同意义,也可用于取消所有元字符 \d 匹配任何十进制数,相当于[0-9] \D 匹配任何非数字字符,相当于[^0-9] \s 匹配任何空白字符,相当于[\t\n\r\f\v] \S 匹配任何非空白字符 \w 匹配任何字母数字字符 \W 匹配任何非字母数字字符 *-匹配前一个字符零次或多次 +-至少

C++面向对象高级编程(二)

版权声明:本文为博主原创文章,未经博主允许不得转载. 接下来的几篇文章,我将回忆一下C++的基础. C++的由两部分组成 1.C++语言 2.C++标准库 本篇文章主要分享我学习C++语言的笔记. 这次主要回忆一下操作符重载. 先看一段代码,后续我会介绍这么做的原由 #include <iostream> class complex { public: complex(double r = 0, double i = 0) : re(r) ,im(i) {} complex& oper

python学习笔记之面向对象、类以及I/O操作

一.I/O 操作: open(name[,mode]) 等价于file(name[,mode]) 模式说明: r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在. w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失.若文件不存在则建立该文件. w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失.若文件不存在则建立该文件. a 以附加的方式打开只写文件.若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被