反射这个词我一直没搞懂,也不知道为什么需要反射,也不知道反射到底做了什么。所见所闻逐渐丰富之后,开始有点儿懂了。

先不管反射这个词是什么意思。Java 里面有反射,Python 里面也有反射,但是不太有人强调 Python 里面的反射,可能是因为 Python 是解释的语言,天然的容易获得运行时的类型信息。

C 语言是最贴近硬件的编程语言。C 语言编译到汇编以后,汇编只有指令,寄存器。根本不管什么 int, float, struct date。从汇编我们只知道用哪个寄存器,往哪个地址写东西,从哪个地址读东西,一次读也就最多读一个寄存器的大小,具体一点大概是64位或者32位。C 语言的程序里面的变量在运行的时候不知道他是什么类型,只在编译的时候知道一个变量占多少个字节。

Java 和 Python 都是有一个 VM 用来运行从源码编译到的字节码。Python 的 OOP 世界一切都是对象,变量,字面量是对象,类型也是对象。我们可以通过obj.attr的方式访问对象的属性,对于这种动态解释的语言来说,方法也是属性。在 Python 可以轻松获得一个对象的有关信息,包括它的类型。使用type()函数可以知道一个对象的类型。

>>> str
<class 'str'>
>>> type(str)
<class 'type'>
>>> type
<class 'type'>

一切皆对象,类也是对象,类是<class 'type'>的对象。str 这个类是 <class 'str'>,而 str 这个类的类是 type。好吧,很绕了。声明一个类就是声明了一种新的类型,类型也是对象,类型是 type 的对象。那么如果还要追究 type 是谁的对象,那目前我只能说就像盘古开天辟地,混沌初始一样,自这个世界开始,混沌就是这个世界开始的起点(如果你相信的话)。type 由 VM 建立,而 VM 就是我们造的混沌,我们也是盘古直接将 VM 需要的东西都建立了起来。

实际上,Python 的类的机制完全可以用 Python 的函数来实现1。用 class MyClass 这种语法声明一个类,完全可以当做是一个函数,加载/构造这个类的时候这个函数体被执行,然后函数体的本地变量都变成了这个新类方法和类的属性。这个类是通过type()构造的。而所有的类型的属性都可以从对象获得。

>>> str
<class 'str'>
>>> str.__name__
'str'
>>> 'Hello'.__class__
<class 'str'>
>>>

Python 的每个模块只会被 evaluate 一次。import 一个模块的时候模块内的代码被执行,模块内的 class 里的语句也被执行,每个 class 都是被 type 实例化出来的类型。

在 Python 的世界获取对象的类型特别简单,都在对象的属性里面了。不知不觉就已经用到了反射了,从一个对象获得它的类型,这就是反射做的事情。Python 的类的加载是执行类的定义,所有的类都是 type 的实例。而 Java 也有类似之处。

Java 所有的类都是 Class 这个类的实例,而所有的对象都有一个 class 属性,可以获取对象的类。而 Java 是加载完必要的类之后,用到类的时候才去装载类。Python 是 import 一个类,或者类被 type 制造出来的时候完成类的装载。装载或者加载一个类,制造出来类型的时候,类的代码被执行。

通过反射可以在运行时刻知道对象的类型信息。Java 可通过Class.forName()去加载一个类,Python 可以通过 import 类来加载类,加载类的时候类的代码被执行。加载完了,就有了新的类型。所以 MySQL 的 JDBC,可以用 Class.forName("com.mysql.cj.jdbc.Driver")加载类,执行类的代码。

浅谈 Java 和 Python 的反射的更多相关文章

  1. 浅谈Java的反射机制和作用

    浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...

  2. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  3. 浅谈Java代理二:Cglib动态代理-MethodInterceptor

    浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...

  4. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  5. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  6. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  7. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  8. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  9. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  10. 浅谈java性能分析

    浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...

随机推荐

  1. Django环境安装

    1.安装Django # 自动安装PyPi提供的最新版本 pip install django # 安装指定版本 pip install django==2.2 # 验证安装 >>> ...

  2. Redis的web管理界面redis-manager

    下载 下载地址:https://github.com/ngbdf/redis-manager/releases 配置 tar -zxv -f redis-manager-2.3.2.2-RELEASE ...

  3. 存储类StorageClass

    存储类概述 StorageClass 存储类用于描述集群中可以提供的存储的类型.不同的存储类可能对应着不同的: 服务等级(quality-of-service level) 备份策略 集群管理员自定义 ...

  4. Node Exporter监控指标

    访问http://localhost:9100/metrics,可以看到当前node exporter获取到的当前主机的所有监控数据,如下所示: 每一个监控指标之前都会有一段类似于如下形式的信息: # ...

  5. python中限定导入的子模块

    如果包定义文件__init__.py中存在一个叫做__all__的列表变量,那么在使用from package import *的时候就把这个列表中的所有名字作为要导入的模块名. 例如在example ...

  6. Java 基础三、接口与内部类

    1.   在Java程序语言中,接口是对类的一种描述.例如Arrays类中sort方法声明可以对对象进行排序,但前提是对象所属的类必须实现Comparable接口. public interface ...

  7. 货币转换I

    A=input() if A[0] in ['U','u']: RMB=(eval(A[3:]))*6.78 print("RMB{:.2f}".format(RMB)) else ...

  8. PHP全栈开发(六):PHP与HTML页面交互

    之前我们在HTML表单学习这篇文章里面创建了一个HTML页面下的表单. 这个表单是用户用来输入数据的 具体代码如下 <!DOCTYPE html> <html> <hea ...

  9. NOIP2003 普及组 洛谷P1045 麦森数 (快速幂+高精度)

    有两个问题:求位数和求后500位的数. 求位数:最后减去1对答案的位数是不影响的,就是求2p的位数,直接有公式log10(2)*p+1; 求后500位的数:容易想到快速幂和高精度: 1 #includ ...

  10. 浅谈MySQL、Hadoop、BigTable、Clickhouse数据读写机制

    个人理解,欢迎指正 数据库 引擎 写数据 读数据 补充 MySql InnoDB:支持事务,高速读写性能一般 Myisam:不支持事务,高速读写性能好 以InnoDB更新一条记录为例 1.B+Tree ...