-
2021-06-03 16:06:48
类是对象的抽象,对象是类的实例 是 正确的
看:https://www.cnblogs.com/marlanchen/p/11563929.html【转载】
更多相关内容 -
Python元类和新型类-对象是类的实例,那类又是谁的实例?
2021-02-16 15:14:32既然对象是以类为模板生成的,那么类又是以什么为模板生成的? 元类具有动态改变类的能力,给编程带来了更方便的动态性和能力。 新型类相比于传统类,支持更多特性和机制,有更多的弹性。 文章目录 元类 类工厂 初始...元类
既然对象是以类为模板生成的,那么类又是以什么为模板生成的?
事实上绝大部分情况下都都不是必须使用元类才能完成开发,但是元类动态地生成类的能力能更方便地解决下面情景的难题:
- 类在设计时不是所有细节都能确定,有些细节需要程序运行时得到的信息才能决定。
- 类比实例更重要的情况,如用声明性语言在类声明中直接表示了它的程序逻辑,使用元类来影响类的创建过程就相当有用。
类工厂
在Python老版本中,可以使用类工厂函数来创建类,返回在函数体内动态创建的类。
类工厂的方法是通过一个函数来生产不同的类。类工厂可以是类,就像它们可以是函数一样容易。
例如:def class_with_method(func): class klass: pass setattr(klass, func.__name__, func) return klass def say_tip(self): print('记得一键三连~') Tip = class_with_method(say_tip) tip = Tip() tip.say_tip()
函数
class_with_method
是一个类工厂函数,通过setattr()
方法来设置类的成员函数,并且返回该类,这个类的成员方法可以通过class_with_method
的func
参数来指定。
初始元类
在Python2.2之后,type特殊类就是这样的类工厂,即所谓的元类,元类是类的类,类是元类的实例,对象是类的实例。
元类type使用方法:def say_tip(self): print('记得一键三连~') Tip = type('Tip',(),{'say_tip':say_tip}) tip = Tip() tip.say_tip()
元类type首先是一个类,所以比类工厂的方法梗灵活多变,可以自由的创建子类来继承扩展元类的能力。例如:class ChattyTypr(type): def __new__(cls, name, bases, dct): print("分配内存空间给类",name) return type.__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct): print("初始化类", name) super(ChattyTypr, cls).__init__(name, bases, dct) a = ChattyTypr('Test',(),{})
其中,
__new__
分配创建类和__init__
方法配置类是类type内置的基本方法,需要注意的是,第一个蚕食是cls
(特指类本身)而非self
(类的实例)。元类实例化一个类时,类将会获得元类所拥有方法,就像类实例化对象时对象获得类所拥有方法一样,但是注意多次实例化和多次继承的区别:
元类属性
Python中每一个类都是经过元类实例化而来,只不过这个实例化过程在很多情况下都是由Python解释器自动完成的。那么怎么设置元类的属性?
每个类都有一个属性__metaclass__
用来说明该类的元类,该属性一般由解释器自动设置,不过用户也可以更改该属性来更改类的元类。可以在类的内部直接设置__metaclass__
属性,也可以设置全局变量,那么该命名空间下定义所有类的元类都将是全局变量__metaclass__
所指定的元类。class ChattyTypr(type): def __new__(cls, name, bases, dct): print("分配内存空间给类",name) return type.__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct): print("初始化类", name) super(ChattyTypr, cls).__init__(name, bases, dct) class example(metaclass=ChattyTypr): def __init__(self): print('初始化')
元类作用
改变全局变量
__metaclass
就能改变类的元类,而类又是元类的实例化结果,所以元类可以改变类的定义过程。换句话说,只要改变全局变量__metaclass__
就能改变类的定义,这就是元类的作用了。class example: def __init__(self): print('类example初始化') def say_tip(self): print('记得一键三连') a = example() a.say_tip() class change(type): def __new__(cls, name, bases, dict): def say_tip(self): print('记得点赞关注收藏~') dict['say_tip']=say_tip return type.__new__(cls, name ,bases, dict) class example(metaclass=change): def __init__(self): print('类example初始化') def say_tip(self): print('记得一键三连') a = example() a.say_tip()
面向方面和元类
元类的作用能带来什么实用价值吗?
实际用途确实有的,接近于面向方面编程(Aspect Oriented Programming,AOP)的核心内容,即所谓的“横切关注点”。使用面向对象方法构建软件系统,我们可以利用OO的特性很好地解决纵向问题,因为OO的核心概念(如继承等)都是纵向结构的。
但是软件系统中往往很多模块/类共享某个行为,或者说某个行为存在于软件的各个部分中,看作是横向 存在于软件之中,它所关注的是软件个部分共有的一些行为,而且很多情况下这种行为不属于业务逻辑的一部分。一个软件系统的业务逻辑很大一部分代码都是AOP里所说的横切关注点。例如日志处理、安全检测、事务处理、权限检测等占比很大,几乎每个地方都要调用。AOP的思想就是把这些横切关注点代码都抽取出来,不再在各个软件模块中显示使用。
以日志处理为例,一般习惯在做一些操作前写上开始模块处理的每个步骤都需要由正常日志和异常日志,那么这个软件光是写日志的代码就要成千上万行了,维护起来相当困难。
如果部分代码不需要手工写到各个业务逻辑处理的地方,而是把这部分代码独立出来,那么在各个业务逻辑处理的地方,会在运行的时候自动调用这些横切关注点功能,这样代码量就少很多,这就是AOP的核心思想。
要实现AOP所说的自动调用,有的语言使用AspectJ编译器,Python则使用元类。
小结
元类具有动态改变类的能力,给编程带来了更方便的动态性和能力。
实际使用过程中,需要防止过度使用元类来改变类,过于复杂的元类通常会带来代码难以和可读性差的问题,所以一定要在确实需要使用是再使用元类。新型类
Python在2.2版本后,新引入了两种不同的类:新型类和传统类/经典类。Python的对象世界相比也发生了重大变化。
新型类VS传统类
老版本的Python中不是所有的元素都是对象,内置的数值类型都不能被继承,而在版本2.2后,任何内建类型也都是继承自object类的类,凡是继承自类object或者object子类的类都是新型类,而不是继承自object或object子类的都成为传统类。
新的对象模型于传统模型相比有小但是很重要的优势,Python版本对传统类的支持主要是为了兼容性,所以使用类的时候推荐从现在开始直接使用新型类。在Python3版本将放弃兼容性,即Python3.X版本中只存在新型类。
新型类继承自object或object子类,实际上所有的内建类型都是从object继承而来,可以用
issubclass()
函数验证,当存在子类和父类关系时返回True,否则返回False。
(
插播反爬信息)博主CSDN地址:https://wzlodq.blog.csdn.net/静态方法和类方法
新的对象模型提供了两种类的方法:静态方法和类方法。
静态方法可以直接被类或类的实例调用,没有常规方法的那样限制(绑定、非绑定、默认第一个参数规则等),即静态函数的第一个参数不需要指定为
self
,也不需要只有对象(类的实例)才能调用。使用关键字@staticmethod
定义。如下定义静态方法、常规方法(第一个参为
self
和不带self
两种)class Test(object): @staticmethod def static_tip(str): print(str) def normal_tip(str): print(str) def normal_tip2(self,str): print(str)
- 使用类调用
直接使用类调用时,不需要传入self表示具体的类的实例,即报错只传了一个参数。
- 使用对象(类的实例)调用
使用对象调用时,自动将类实例对象作为第一个参数传给该方法,即报错给了两个参数。
类方法不管是使用类来调用还是使用对象(类的实例)来调用,都是将类作为第一个参数传入。使用关键字
@classmethod
定义。
特定方法
__new__
方法
当一个类C调用C(*args,**kwds)
创建一个C类实例时,Python内部实际上调用的是C.__new__(C,*args,**kwds)
。new方法的返回值x就是该类的实例对象,new即用来分配内存生成类的实例。
注意第一个参数是cls
(即这里写的类C),用来接受一个类参数,然后才能返回该类的实例。
使用new方法可以实现一些传统类无法做到的功能,例如让类只能实例化一次:
__init__
方法
当调用new方法分配内存创建一个类C对象后,Python判断该实例是该类的实例,然后会调用C.__init__(x,*args,**kwds)
来初始化这个实例,x就是new方法的返回值,init即对类实例对象做初始化操作。
注意第一个参数是self
(即这里写的x)表示接受类的实例对象。
上述实例化对象代码c = C()
就等价于:
__getattribute__
方法
__getattribute__
负责实现对象属性引用的全部细节。新型类在调用它自身的类或方法是,实际上都是先通过该方法来调用。
因为新型类调用自身属性和方法时都会先调用__getattribute__
方法,所以可以实现一些新功能,如隐藏父类的方法:
特定属性
内建
property
类用来绑定类实例的方法,并将其返回值绑定为一个类属性,语法:
attrib = property(fget=None, fset=None, fdel=None, doc=None)
设类C通过
property
创建了属性attrib
,x是类C的一个实例。- 当引用
x.attrib
时,会调用fget()
方法取值; - 当为
x.attrib
赋值时,会调用fset()
方法; - 当执行删除
del x.attrib
时,会调用fdel()
方法; doc
参数为该属性的文档字符串。
如果不定义
fset()
和fdel()
方法,那么该属性将是一个只读属性。property
可以方便地将一个函数的返回值转换为属性,这下操作就很灵活方便了。
比如定义一个长方形类,如果要将它的面积也作为一个属性,就可以用property
将计算面积的方法绑定为一个属性:class Rectangle(object): def __init__(self,width,height): self.width=width self.height=height def getArea(self): return self.width*self.height area = property(getArea(),doc='长方形的面积')
上述代码中,
getArea()
是计算面积的方法,使用property
将该方法的返回值转换为属性area
,这样引用Rectangle的area
是,Python会自动使用getArea()
计算出面积。同时由于该例中只定义了fget()
方法,所以area
是一个只读属性。super()方法
新型类提供了一个特殊的方法
super()
。super(aclass,obj)
返回对象obj是一个特殊的超对象(superobject)。当我们调用该超对象的一个属性或方法时,就保证了每个父类的实现均被调用且仅仅调用了一次。以下时直接调用父类的同名方法,无法避免类A的方法被重复调用:
class A(object): def test(self): print('A') class B(A): def test(self): print('B') A.test(self) class C(A): def test(self): print('C') A.test(self) class D(B,C): def test(self): print('D') B.test(self) C.test(self) d = D() d.test()
以下时使用
super()
方法,保证父类方法均调用一次:class A(object): def test(self): print('A') class B(A): def test(self): print('B') super(B, self).test() class C(A): def test(self): print('C') super(C, self).test() class D(B,C): def test(self): print('D') super(D, self).test() d = D() d.test()
小结
新型类相比于传统类,支持更多特性和机制,有更多的弹性。例如可以定制实例化的过程,尤其时在多重继承的情况下能避免传统类存在的缺陷。而事实上Python3.X版本中已经不存在传统类了,目前传统类存在的意义主要是为了保持之前的兼容性。
原创不易,请勿转载(
本不富裕的访问量雪上加霜)
博主首页:https://wzlodq.blog.csdn.net/
微信公众号:唔仄lo咚锵
如果文章对你有帮助,记得一键三连❤ -
python下,类对象和实例对象区别,类变量和实例变量区别
2018-10-13 15:06:52类对象是将具有相似属性和方法的对象总结抽象为类对象,可以定义相似的一些属性和方法,不同的实例对象去引用类对象的属性和方法,能减少代码的重复率。 实例对象又称实例化对象,不是抽象而是一类对象中具体的一例...Y14
一、类对象和实例对象
简短理论:- 类对象是将具有相似属性和方法的对象总结抽象为类对象,可以定义相似的一些属性和方法,不同的实例对象去引用类对象的属性和方法,能减少代码的重复率。
- 实例对象又称实例化对象,不是抽象而是一类对象中具体的一例对象。
比喻理解:
我相信有的人觉得有点绕,在这里我以比喻说明,希望你能明白。首先,要明白,在python中,“万物皆对象”。个人理解:类对象,好比有一篮“水果”,篮子里面的水果没有重复,那么这一篮中的“水果”就属于一个类,是抽象的,就像有人对你说“给我水果”,你的第一反应一定是“什么水果?”,所以是不确定性的。
实例对象,好比篮子里面的“苹果”,是一个具体的对象,即一个实例。我想有人对你说“给我苹果”,你应该不会想选择哪个水果吧
二、类变量和实例变量
简短理论:- 类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。
- 实例变量:实例化之后,每个实例单独拥有的变量。实例变量:实例化之后,每个实例单独拥有的变量。
比喻理解:
其实,如果你理解了类对象和实例对象,在看过类变量和实例变量的理论,应该就能明白区别。类变量,接上面一篮水果比喻,好比是说“洗洗水果”(洗这个新加的动作就是你定义的一个类变量),你肯定是篮子里面的所有水果都会洗。也就是所有的水果都共享了“洗”这个新加的动作。即“类变量的值,实例可以共享”
实例变量,这个简单,好比说“洗洗苹果”,这个洗的动作是有针对性的,是作用于一个苹果(实例)。即为“实例化后,每个实例单独拥有的变量”
大家需要注意,以上问题也是python中常见面试题,若需代码理解,推荐:https://www.cnblogs.com/loleina/p/5409084.html ,愿你理解。
个人小结,定有不足之处,欢迎指点。
谢谢~ -
Python学习:类、类对象和实例对象
2019-01-24 13:01:43# 类定义C class C: count = 0 # 类对象C() a = C() ...# 实例对象a,b ...可以看出对实例对象a的count属性进行赋值之后,就相当于覆盖了类对象C的count属性。如果没有赋值覆盖,那么引用的是类对象的co...一、概念
将“鸟类”想象成所有鸟的集合,所以“百灵鸟”是“鸟类”地子类;相反,“鸟类”是“百灵鸟”的超类
# 类定义C class C: count = 0 # 类对象C() a = C() b = C() c = C() # 实例对象a,b a.count += 100 print(a.count,b.count,c.count) #返回结果:100 0 0
可以看出对实例对象a的count属性进行赋值之后,就相当于覆盖了类对象C的count属性。如果没有赋值覆盖,那么引用的是类对象的count属性。
二、补充
- Python中的私有特性
为了让方法或者特性变为私有(从外部无法访问)只要在它的名字前面加上双下划线即可
虽然外界无法访问,在类内部还是可以使用的
实际上也是有方法在类外访问这些私有方法的
- Python中的私有特性
-
【Java反射】通过类对象创建一个实例对象
2021-06-17 15:49:49通过构造器对象获取实例对象。 TestReflection2.java package study; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class TestReflection2 { public ... -
类对象与实例对象
2019-05-08 14:19:56什么是对象? 1.世间万物皆为对象:问题...5.对象分为类对象和实例对象两大类:类对象是具有相同属性和行为的实例对象的抽象。同一类对象的所有实例对象如果具有相同的属性,表明它们的状态不一定相同,即属性的取值... -
类,对象,实例
2020-02-19 13:35:45类,对象,实例 之前一直将对象和实例区分不清楚,最近思考了下,整理如下 类—实例化—>对象 实例是相对于某一个具体类的概念,a对象是B类的实例。 类是对象的集合(抽象) 类实例化为对象,因此所谓的实例是... -
Python-类对象方法和类实例对象方法
2018-06-05 13:33:26自己总结python类中类对象方法和... (3)除了以上两条外,至少带一个参数的方法定义,且没有classmethod标识的,肯定为实例对象方法(第一个参数实际上是类实例对象self,比较隐含)。请大家分析如下代码:# -*- ... -
C#面向对象_静态和实例,静态类和实例类,静态成员和实例成员
2020-12-12 14:23:04一、C#静态和实例概念 静态概念:公共的、全局的、不属于个别实例的定义。 实例概念:new 出来的具体单个对象。随着作用域定义,使用,销毁(多数实例,通过垃圾回收机制自动销毁)。...二、C#静态类和实例类 . -
什么是类 对象 实例
2014-11-11 15:51:10类(Class)实际上是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础 http://baike.baidu.com/view/2390.htm 对象(object)是一件事、一个实体、一... -
3.2、抽象一个类和实例化对象
2018-03-28 19:20:36一、抽象一个类 二、实例化对象 1、实例化对象 2、对象类型在内存中分配情况 三、$this 四、构造函数和析构函数 -
类,实例,对象,生成对象,实例化对象的区别(精讲)
2018-02-07 14:45:07问题简述 什么是类? 什么是实例? 什么是对象? ... 什么是生成对象?... 什么是实例化对象?... 在面向对象程序设计中,... 对象就是类的实例,所有的对象都是类的实例,但并不是所有的实例都是对象。 抽象类被定义为... -
Python——定义基本的类,并且将类实例化为对象
2019-07-16 21:39:431.如何定义类 模板:class 类名(继承):pass(属性、方法) 注意类名的命名中没有下划线,这一点和变量...2.类创建对象的过程称为实例化,把抽象的类具体化 模板:对象名 (任意)= 类名(参数1、参数2…参数n) ... -
JAVA 类和对象的实例
2019-01-15 11:01:23JAVA 类和对象的实例 什么是类? 1. 类是具有相同的属性和功能的事物的抽象的集合,在面向对象程序设计中,人们把一类事物的静态属性和动态可以执行的操作组合在一起就得到类这个概念。 2. 类是个抽象的概念,用来... -
java判断对象是否是一个类的实例
2019-07-05 14:34:01Java:如何判断一个对象是否是特定类的实例 一、InstanceOf运算符 InstanceOf运算符是用来在运行时指出对象是否是特定类的一个实例。InstanceOf通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的... -
什么是类的实例化,类的对象?
2017-05-09 12:19:46如何理解Student stu = new Student()? stu是什么?能做什么? -
Java:如何判断一个对象是否是特定类的实例
2019-04-09 19:23:31Java:如何判断一个对象是否是特定类的实例 一、InstanceOf运算符 InstanceOf运算符是用来在运行时指出对象是否是特定类的一个实例。InstanceOf通过返回一个布尔值来指出,这个对象... -
Java中子类中子类实例化父类对象
2019-05-03 18:08:39版权声明:博主原创/资料整理,转载请注明出处!! 写一个父类,里面有两个方法,doing ()和talking(),并在doing ()方法中调用talking()方法。...3. 子类中,子类实例化子类对象,调用子类中的方法。 -
Java中实例化对象是什么意思
2021-02-22 20:45:53在Java语言中使用new关键字创建/构造对象的过程叫做类的实例化,该过程的本质,会在内存空间的堆区申请一块存储区域,用于记录该对象独有的成员变量信息。 通俗点就是,实例化:使用关键字new来创建对象。 例如: ... -
Java如何在main方法中实例化内部类对象
2019-03-11 15:33:42今天我在实例化一个类是编译器报以下错误: No enclosing instance of type Person is accessible. Must qualify the allocation with an enclosing instance of type Person (e.g. x.new A() where x is an ... -
第7.14节 Python类中的实例方法详析
2020-12-19 01:11:31第7.14节 Python类中的实例方法详析一、 实例方法的...定义实例方法与定义函数基本相同,只是Python要求实例方法的第一个形参必须为self,也就是实例对象本身,因此实例方法至少应该有一个self参数。关于self的说... -
【面向对象-05】什么是类变量、实例变量、以及区别
2020-05-01 21:02:12一、类变量和实例变量的定义 |-成员变量:把类内、方法体外定义的变量称为成员变量。 |-类变量:有static修饰,称为类变量(静态变量); |-随着类的加载而加载; |-优先于对象存在; |-被所有对象所共享; |-... -
Python类对象成员与类实例对象成员
2018-06-05 13:49:34#Person类对象成员Count公有。 _income=0; #Person类对象成员income保护,其派生类可以引用。 __Tel="13088888888" #Person类对象成员Tel,是私有,在类定义中可以引用。 def __init__(self,name,... -
Java判断该对象是否是某一个类的实例_instanceof运算符
2020-09-07 13:46:32一、instanceof运算符:判断该对象是否是某一个类的实例。 语法格式:booleanb =对象A instanceof 类B; 判断 A对象是否是 B类的实例?如果是,返回true 二、演示代码: -
类、对象、方法、实例方法、类方法
2019-02-20 16:32:00静态方法:1、在被实例化之前就已经存在于内存中,2、静态方法是类所有对象共有的方法,3、可被类或对象调用;非静态方法:1、在类被实例化之后,才加载到内存中,具体存储在堆中;2、非静态方法被对象所私有;3、... -
深入理解Java对象的创建过程:类的初始化与实例化
2017-05-18 14:17:45在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完成类的初始化。在类初始化过程中或初始化完毕后,根据具体情况才会去对类进行实例化。本文试图对JVM... -
Python如何使用类对象调用实例方法
2020-05-06 15:29:40在前面的学习中,我总结了...我们知道,实例对象可以调用这三种方法,而类对象只能调用类方法和实例方法,既然如此为何我们还要研究类对象调用实例方法呢?我们先看一个例子: class Dog: def action(self): ... -
实例化对象是什么意思,什么是实例化,什么是对象。多态性
2020-01-06 14:48:46书中说对象和类的实例的含义相同。 那么怎么完成实例化呢。我们创建一个对象需要对它初始化数据。能够有这一作用的是什么呢?——构造函数。所以就有了 Car mycar= new Car(); 当我们自己定义了与类同名的有参构造... -
判断某个实例对象是否属于某个类方法总结
2020-01-03 00:28:36总结下判断某个实例是否属于某个类的...InstanceOf运算符是用来在运行时指出对象是否是特定类的一个实例。InstanceOf通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。 用法也非常简单... -
对象实例数据和对象类型数据
2019-07-30 16:32:29对象类型:对象中各个实例字段的数据 对象类型数据:对象的类型、父类、实现的接口、方法等