面向对象,元类,控制类,对象的创建

"""

call

调用的意思 ? 在在对象被调用时 执行

函数 类

自定义元类 的目的 ? 1.可以通过call 来控制对象的创建过程 ? 2.可用控制类的创建过程 """

自定义一个元类 元类也是一个类 但是需要继承type
class MyMeta(type):?self 表示要创建对象的那个类(Person) *args是调用Person类时传入的参数??  def __call__(self, *args, **kwargs):??      print("MyMte中的 call run‘")

print(*args)       #Person的参数?print(self)                 #person 类?下面的三步是固定写法 一个模板 只要你需要控制对象的创建过程 就应该先把模板写出来?1.创建空对象??      obj = object.__new__(self)?2.调用初始化方法??      self.__init__(obj,*args,**kwargs)?3.得到一个完整的对象??      return obj?修改Person类的元类为MyMeta?class Person(metaclass=MyMeta):??  def __init__(self,name,age):?      self.name = name?      self.age = age??  def __call__(self, *args, **kwargs): #程序运行的就会自动运行?      print("call run...")?调用Person这个对象时 执行的是 Person的类(type)中__call__ 方法?p = Person("张三",80)?print(p)?当调用对象时 会执行该对象所属类中的__call__方法?p()?print(p.name)print(p.age)??

练习:

class My(type):  obj = None  def __call__(self, *args, **kwargs):      if not My.obj:          print(‘yes‘)          obj = object.__new__(self)          self.__init__(obj,*args, **kwargs)          My.obj = obj      return My.obj?class Orange(metaclass=My):  def __init__(self,name,type_1,price):      self.name = name      self.type = type_1      self.price = price  def forma(self):      print(self.__dict__)o1 = Orange(‘金水橘‘,‘橘子‘,40)o1.forma()

练习2:

class CarMeta(type):?  def __call__(self, *args, **kwargs):?  if len(args) < 3:      raise ValueError("必须包含三个参数.....")  obj = object.__new__(self)  self.__init__(obj,*args,**kwargs)?  if not("production_date" in obj.__dict__    and "engine_number" in obj.__dict__   and "capacity" in obj.__dict__):      raise ValueError("必须包含 生产日期,发动机编号,载客容量")  return obj??class BigCar(metaclass=CarMeta):?  def __init__(self,production_date,engine_number,capacity):?      self.production_date = production_date?      self.engine_number = engine_number?      self.capacity = capacity?c = BigCar("2018 12 21","e-1-3-q-f",5)print(c)

要控制类的创建过程 只要找到类所属的类 中的init即可

class MyMeta(type):?1. self 刚建出来的类2. 第二个 类的名字3. 第三个 类的父类们 元组4. 第四个 这个类传进来的名称空间?  def __init__(self ,class_name ,bases ,namespace):      print("============================")?# print(self.__dict__)?# 我要控制 类的名字 必须 是大写开头?      if not class_name.istitle():          print("类名 必须大写开头...... ")?# 该代码是主动抛出异常?          raise TypeError("类名 必须大写开头...... ")?# 要空类的创建 必须包含__doc__这个属性?      if not self.__doc__:          raise TypeError("类中必须有文档注释.....")?      pass?class Student(metaclass=MyMeta):   # Student = MyMeta("Student",(object,),{})  """      这是文档注释 可以通过__doc__来获取      这是一个学生类  """?# 在类的__init__中可以控制该类对象的创建过程?  def __init__(self ,name):      print("-----------------------")      print(self.__dict__)      self.name = name?print(Student.__doc__)

元类使用总结:

""" 元类是用于创建类的类 学习元类是为了 能控制类的创建过程 以及 类实例化对象的过程

一. 控制类的创建过程 ? 1.创建一个元类 (需要继承type) ? 2.覆盖init方法 该方法 会将新建的类对象 类名 父类们 名称空间 都传进来 , ? 可以利用这些信息在做处理 ? 3.对于需要被控制的类 需要指定metaclass 为上面的元类

二. 控制类实例化对象的过程 ? 1.创建一个元类 (需要继承type) ? 2.覆盖call方法 会将 正在实例化对象的类 调用类是传入的参数 都传进来 ? 3.在call方法中 必须要先编写模板代码 ? 3.1创建空对象 ? 3.2调用类的init方法来初始化这个空对象 ? 3.3返回该对象 ? 4.加入你需要控制的逻辑

类的三个组成部分 类名 父类们 名称空间

元类 -> 实例化产生 -> 类 -> 实例化产生 -> 对象

"""

练习:

组合创建类的创建对象的技巧

class My(type):  def __init__(self,a,b,c):      if not a.istitle():          print(‘首字母注意大写‘)          raise TypeError(‘类名开头必须大写‘)      if not a.__doc__:          print(‘注释为空‘)          raise TypeError(‘请添加注释‘)  obj = None  def __call__(self, *args, **kwargs):      print(‘yes‘)      if not My.obj:          obj = object.__new__(self)          self.__init__(obj,*args, **kwargs)          My.obj = obj      return My.objclass Tree(metaclass=My):  def __init__(self,name,age):      self.name = name      self.age = age  def breath(self):      print(‘这颗%s的%s的大树很粗壮‘%(self.age,self.name))t1=Tree(‘衫树‘,30)print(t1)t2=Tree(‘衫树‘,30)print(t2)t1.breath()

单例

""" ? 单例模式 ? 一种设计模式(套路)

单个实例 ? 一个类如果只有一个实例 那么该类称之为单例

为什么需要单例

当要处理的数据全部相同时,比如打印机复印文件时

"""

代码1:

?class Printer():  """  这是一个单例类 请不要直接实例化 使用get方法来获取实例  """?  obj = None  def __init__(self,name,brand,type):      self.name = name      self.brand = brand      self.type = type?  def printing(self,text):      print("正在打印 %s" % text)

以下三个对象 的数据完全相同 但是却 占用三分内存空间

p1 = Printer("ES005","爱普生","彩色打印机")?p2 = Printer("ES005","爱普生","彩色打印机")?p3 = Printer("ES005","爱普生","彩色打印机")

用类调用:

obj = None           #定义了类的属性  @classmethod  def get_printer(cls):      if not cls.obj:          obj = cls("ES005","爱普生","彩色打印机")          cls.obj = obj          print("创建了新的对象")?      return cls.obj

通过该方法来获取对象 可以保证只有一个对象

p = Printer.get_printer()print(p)?p = Printer.get_printer()print(p)?p = Printer.get_printer()print(p)?p = Printer.get_printer()print(p)# 内存地址都相同

通过该方法来获取对象 可以保证只有一个对象

但是这还不够 因为 还是可以通过调用类产生新对象

就应该使用元类 来控制实例化的过程 call

call 中编写代码 保证每次调用call 都返回同一个实例 即可

现在要处理问题就是 如何能够限制该类 只能实例化一个对象

元类

代码2:

class My(type):  obj = None  def __call__(self, *args, **kwargs):      if not My.obj:          obj = object.__new__(self)          self.__init__(obj, *args, **kwargs)          My.obj = obj      return My.obj       class Printer(metaclass=My):  """  这是一个单例类 请不要直接实例化 使用get方法来获取实例  """  def __init__(self,name,brand,type):      self.name = name      self.brand = brand      self.type = typedef printing(self,text):      print("正在打印 %s" % text)       p1 = Printer("ES005","爱普生","彩色打印机")p2 = Printer("ES005","爱普生","彩色打印机")?print(p1)print(p2)#内存地址全部一样p1.printing("一本小说....")

元类的思想就是控制对象,所有对象全部都要在call走一遍,才能返回到类里使用。因此在第一次经过元类时,元类就通过赋值给固定死了,以后都不会再初始化了。

了解:

代码1:

class MyMeta(type):?# 用于新建类对象?  def __new__(cls, *args, **kwargs):      print("new run")?print(MyMeta)?print(*args)?调用type通过的__new__方法来创建一个空的类对象 已经将三个组成部分都放到类对象中了?      res = type.__new__(cls,*args)      return res?  def __init__(self,class_name,bases,namespace):      print("init run")      print(self)???class Student(metaclass=MyMeta):  pass?print(Student)

""" new 与 init的区 newinit先执行 其作用是创建一个空的类对象 作为一个类对象 必须具备是三个组成部分 所以调用type中的new来完成组装 得到这个类对象后需要将其返回 以供init来使用

"""

原文地址:https://www.cnblogs.com/wang-kai-1994/p/10167241.html

时间: 2024-07-29 15:13:01

面向对象,元类,控制类,对象的创建的相关文章

2.自定义元类控制类的创建行为

工作中,现有的类可能不能满足实际的个性化需求,那么我们需要自己定义元类来控制类的行为 本篇是对自定义元类控制类的创建行为的理解 自定义元类控制类型为分创建行为和实例化行为,其中控制创建行为是通过__Init__方法实现的. 1)我们知道,根据开发规范,类的名称是要大写的,但开发者不大写当然也可以运行的 2)开发者在创建类时,最好在类中加入一些注释,方便以后回头理解,也方便产品经理的理解,当然开发者不写这些注释也没关系 现在我要告诉你,类名必须大写!新建类必须要有注释!就是这么任性,哈哈 实现代码

1.元类介绍/2.自定义元类控制类的行为/3.控制类的实例化行为/4.控制类的实例化行为的应用

1.元类介绍 1.储备知识exec()参数1;字符串形式得命令参数2.全局作用域(字典形式),如果不指定默认就使用globals()参数3.局部作用域(字典形式),如果不指定默认就使用locals() 2.python 一切皆对象 ,对象可以怎么用? 2.1. 都可以被引用 x=obj 2.2. 都可以当作函数得参数传入 2.3. 都可以当作函数得返回值 2.4. 都可以当作容器类得元素 li=[func,time] # 类也是对象,Foo=type() 类是属于type() 类 3.什么叫元类

通过元类控制类的调用过程

__call__ 控制类的调用过程,实际上在控制:对象的产生 class Mymeta(type): def __call__(self,*args,**kwargs): #print('xxx') return 1 class Person(object,metaclass=Mymeta): school = 'oldboy' def __init__(self,name): self.name =name def score(self): print('分数是100') p =Person(

《JVM》(四)Class类文件结构,对象的创建

Class类文件结构 class文件是一组以8字节为单位的二进制流,只有两种数据类型:无符号数(基本数据类型),表(复合数据类型) 魔数 版本号 常量池(占class空间最大的数据之一,从1开始计数) 1.字面量 :接近于java层面的常量概念,如字符串,声明为final的常量 2.符号引用:类和接口的全限定名,字段和方法的描述符 字段描述符:描述字段数据类型 方法描述符:描述方法参数列表和返回值 访问标志 类索引,父类索引,接口索引集合 字段表集合(描述接口或类中声名的变量,不包括方法中的局部

通过元类控制类的产生

自定义元类:来控制类的产生:可以控制类名,可以控制类的集成父类,控制类的名称空间 type 自定义元类必须集成type,写一个类继承type 这种类都叫元类 class Mymeta(type): #def __init__(self,*args,**kwargs): def __init__(self,name,bases,dic): #sef就是Person类 print(name) print(bases) print(dic) #加限制 控制类名必须以sb开头 if not name.s

Python----面向对象---自定义元类控制类的实例化行为

一.知识储备 1.__call__方法 1 class Foo: 2 def __call__(self, *args, **kwargs): 3 print(self) 4 print(args) 5 print(kwargs) 6 7 obj = Foo() 8 obj() 9 10 结果为: 11 12 <__main__.Foo object at 0x000002AFE2B4BDA0> 13 () 14 {} 实例化时传参 1 obj(1, 2, 3, a=1, b=2, c=3)

自定义元类控制类的实例化行为

#只是储备 __call__方法:# class Foo:# def __call__(self, *args, **kwargs):# print(self)# print(args)# print(kwargs)# obj = Foo()# obj(1, 2, 3, a = 5, g = 8)'''在python中一切都是对象, 此地,Foo也是对象,Foo可以加括号调用,所以 obj也可以加括号调用但是obj这个对象的类的内部必须有__call__方法,此地可以引出, Foo的元类内部也有

3.1.17 自定义元类控制类的实例化的应用--单实例模式

#单例模式#实现方式一:# class MySQL:# __instance=None #__instance=obj1## def __init__(self):# self.host='127.0.0.1'# self.port=3306## @classmethod# def singleton(cls):# if not cls.__instance:# obj=cls()# cls.__instance=obj# return cls.__instance### def conn(se

自定义元类控制类的实例化行为的应用

# 单例模式:对一个类多次实例化,但只实例化出同一个对象class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('类名的首字母必须大写!') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必须有注释

【面向对象】关于利用数组对象的创建底部栏

/*eslint-disable*///底部导航栏组件import React from "react";import {render} from "react-dom";import "./compoments.less";import indexNo from '../images/index-no.png'import indexYes from '../images/index-yes.png'import shopNo from '..