Python自省(反射)指南

首先通过一个例子来看一下本文中可能用到的对象和相关概念。

Python
# -*- coding: utf-8 -*- """ @author:songhao @file: c1.py @time: 2017/12/06 """ #coding: UTF-8 import sys # 模块,sys指向这个模块对象 import inspect def foo(): pass # 函数,foo指向这个函数对象 class Cat(object): # 类,Cat指向这个类对象 def __init__(self, name='kitty'): self.name = name def sayHi(self): # 实例方法,sayHi指向这个方法对象,使用类或实例.sayHi访问 print self.name, 'says Hi!' # 访问名为name的字段,使用实例.name访问 cat = Cat() # cat是Cat类的实例对象 print Cat.sayHi # 使用类名访问实例方法时,方法是未绑定的(unbound) print cat.sayHi # 使用实例访问实例方法时,方法是绑定的(bound) # <function Cat.sayHi at 0x10f52ae18> # <bound method Cat.sayHi of <__main__.Cat object at 0x10e2de9b0>>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# -*- coding: utf-8 -*-
"""
@author:songhao
@file: c1.py
@time: 2017/12/06
"""
 
#coding: UTF-8
import sys #  模块,sys指向这个模块对象
import inspect
def foo ( ) : pass # 函数,foo指向这个函数对象
class Cat ( object ) : # 类,Cat指向这个类对象
     def __init__ ( self , name = 'kitty' ) :
         self . name = name
     def sayHi ( self ) : #  实例方法,sayHi指向这个方法对象,使用类或实例.sayHi访问
         print self . name , 'says Hi!' # 访问名为name的字段,使用实例.name访问
cat = Cat ( ) # cat是Cat类的实例对象
print Cat . sayHi # 使用类名访问实例方法时,方法是未绑定的(unbound)
print cat . sayHi # 使用实例访问实例方法时,方法是绑定的(bound)
 
# <function Cat.sayHi at 0x10f52ae18>
# <bound method Cat.sayHi of <__main__.Cat object at 0x10e2de9b0>>

有时候我们会碰到这样的需求,需要执行对象的某个方法,或是需要对对象的某个字段赋值,而方法名或是字段名在编码代码时并不能确定,需要通过参数传递字符串的形式输入。举个具体的例子:当我们需要实现一个通用的DBM框架时,可能需要对数据对象的字段赋值,但我们无法预知用到这个框架的数据对象都有些什么字段,换言之,我们在写框架的时候需要通过某种机制访问未知的属性。

这个机制被称为反射(反过来让对象告诉我们他是什么),或是自省(让对象自己告诉我们他是什么,好吧我承认括号里是我瞎掰的- -#),用于实现在运行时获取未知对象的信息。反射是个很吓唬人的名词,听起来高深莫测,在一般的编程语言里反射相对其他概念来说稍显复杂,一般来说都是作为高级主题来讲;但在Python中反射非常简单,用起来几乎感觉不到与其他的代码有区别,使用反射获取到的函数和方法可以像平常一样加上括号直接调用,获取到类后可以直接构造实例;不过获取到的字段不能直接赋值,因为拿到的其实是另一个指向同一个地方的引用,赋值只能改变当前的这个引用而已。

1. 访问对象的属性

以下列出了几个内建方法,可以用来检查或是访问对象的属性。这些方法可以用于任意对象而不仅仅是例子中的Cat实例对象;Python中一切都是对象。

Python
# -*- coding: utf-8 -*- import sys def foo(): pass class Cat(object): def __init__(self, name='name'): self.name = name def sayHi(self): print(self.name) cat = Cat('your name') print(cat.name) cat.sayHi() print(dir(cat)) if hasattr(cat, 'name'): setattr(cat, 'name', 'tiger') print(getattr(cat, 'name')) getattr(cat, 'sayHi')() ''' your name your name ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'sayHi'] tiger tiger dir([obj]): 调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内)。obj的默认值是当前的模块对象。 hasattr(obj, attr): 这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。 getattr(obj, attr): 调用这个方法将返回obj中名为attr值的属性的值,例如如果attr为'bar',则返回obj.bar。 setattr(obj, attr, val): 调用这个方法将给obj的名为attr的值的属性赋值为val。例如如果attr为'bar',则相当于obj.bar = val。 '''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# -*- coding: utf-8 -*-
import sys
 
 
def foo ( ) :
     pass
 
 
class Cat ( object ) :
     def __init__ ( self , name = 'name' ) :
         self . name = name
 
     def sayHi ( self ) :
         print ( self . name )
 
 
cat = Cat ( 'your name' )
 
print ( cat . name )
cat . sayHi ( )
 
print ( dir ( cat ) )
if hasattr ( cat , 'name' ) :
     setattr ( cat , 'name' , 'tiger' )
print ( getattr ( cat , 'name' ) )
 
getattr ( cat , 'sayHi' ) ( )
 
'''
your name
your name
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'sayHi']
tiger
tiger
 
dir([obj]):
调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内)。obj的默认值是当前的模块对象。
hasattr(obj, attr):
这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。
getattr(obj, attr):
调用这个方法将返回obj中名为attr值的属性的值,例如如果attr为'bar',则返回obj.bar。
setattr(obj, attr, val):
调用这个方法将给obj的名为attr的值的属性赋值为val。例如如果attr为'bar',则相当于obj.bar = val。
'''

2. 访问对象的元数据

当你对一个你构造的对象使用dir()时,可能会发现列表中的很多属性并不是你定义的。这些属性一般保存了对象的元数据,比如类的__name__属性保存了类名。大部分这些属性都可以修改,不过改动它们意义并不是很大;修改其中某些属性如function.func_code还可能导致很难发现的问题,所以改改name什么的就好了,其他的属性不要在不了解后果的情况下修改。
接下来列出特定对象的一些特殊属性。另外,Python的文档中有提到部分属性不一定会一直提供,下文中将以红色的星号*标记,使用前你可以先打开解释器确认一下。
2.0. 准备工作:确定对象的类型

在types模块中定义了全部的Python内置类型,结合内置方法isinstance()就可以确定对象的具体类型了。

isinstance(object, classinfo):
检查object是不是classinfo中列举出的类型,返回布尔值。classinfo可以是一个具体的类型,也可以是多个类型的元组或列表。
types模块中仅仅定义了类型,而inspect模块中封装了很多检查类型的方法,比直接使用types模块更为轻松,所以这里不给出关于types的更多介绍,如有需要可以直接查看types模块的文档说明。本文第3节中介绍了inspect模块。

2.1. 模块(module)

__doc__: 文档字符串。如果模块没有文档,这个值是None。
*__name__: 始终是定义时的模块名;即使你使用import .. as 为它取了别名,或是赋值给了另一个变量名。
*__dict__: 包含了模块里可用的属性名-属性的字典;也就是可以使用模块名.属性名访问的对象。
__file__: 包含了该模块的文件路径。需要注意的是内建的模块没有这个属性,访问它会抛出异常!

Python
import fnmatch as m print m.__doc__.splitlines()[0] # Filename matching with shell patterns. print m.__name__ # fnmatch print m.__file__ # /usr/lib/python2.6/fnmatch.pyc print m.__dict__.items()[0] # ('fnmatchcase', <function>)</function>
1
2
3
4
5
6
7
8
9
import fnmatch as m
 
print m . __doc__ . splitlines ( ) [ 0 ] # Filename matching with shell patterns.
 
print m . __name__                  # fnmatch
 
print m . __file__                  # /usr/lib/python2.6/fnmatch.pyc
 
print m . __dict__ . items ( ) [ 0 ]      # ('fnmatchcase', <function>)</function>

2.2. 类(class)

__doc__: 文档字符串。如果类没有文档,这个值是None。
*__name__: 始终是定义时的类名。
*__dict__: 包含了类里可用的属性名-属性的字典;也就是可以使用类名.属性名访问的对象。
__module__: 包含该类的定义的模块名;需要注意,是字符串形式的模块名而不是模块对象。
*__bases__: 直接父类对象的元组;但不包含继承树更上层的其他类,比如父类的父类
http://python.jobbole.com/82110/




  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱
潮汐研究作为海洋科学的关键分支,融合了物理海洋学、地理信息系统及水利工程等多领域知识。TMD2.05.zip是一套基于MATLAB环境开发的潮汐专用分析工具集,为科研人员与工程实践者提供系统化的潮汐建模与计算支持。该工具箱通过模块化设计实现了两大核心功能: 在交互界面设计方面,工具箱构建了图形化操作环境,有效降低了非专业用户的操作门槛。通过预设参数输入模块(涵盖地理坐标、时间序列、测站数据等),用户可自主配置模型运行条件。界面集成数据加载、参数调整、可视化呈现及流程控制等标准化组件,将复杂的数值运算过程转化为可交互的操作流程。 在潮汐预测模块中,工具箱整合了谐波分解法与潮流要素解析法等数学模型。这些算法能够解构潮汐观测数据,识别关键影响要素(包括K1、O1、M2等核心分潮),并生成不同时间尺度的潮汐预报。基于这些模型,研究者可精准推算特定海域的潮位变化周期与振幅特征,为海洋工程建设、港湾规划设计及海洋生态研究提供定量依据。 该工具集在实践中的应用方向包括: - **潮汐动力解析**:通过多站点观测数据比对,揭示区域主导潮汐成分的时空分布规律 - **数值模型构建**:基于历史观测序列建立潮汐动力学模型,实现潮汐现象的数字化重构与预测 - **工程影响量化**:在海岸开发项目中评估人工构筑物对自然潮汐节律的扰动效应 - **极端事件模拟**:建立风暴潮与天文潮耦合模型,提升海洋灾害预警的时空精度 工具箱以"TMD"为主程序包,内含完整的函数库与示例脚本。用户部署后可通过MATLAB平台调用相关模块,参照技术文档完成全流程操作。这套工具集将专业计算能力与人性化操作界面有机结合,形成了从数据输入到成果输出的完整研究链条,显著提升了潮汐研究的工程适用性与科研效率。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值