python—类对象和实例对象的区别
最近在对RF的通讯层的模块进行封装,需要将之前放在类似main里面的一个方法,如下所示:这段代码是开发提供,用于接口测试,模拟底层通讯,具体的通讯是在dll内,python这边只是做了个封装让RF进行调用。这段通讯层的代码实质上做了五件事:
第一:加载dll;
第二:初始化dll内的通讯参数;
第三:与服务器进行连接,创建session
第四:把数据senbuffer通过sessionManger发送给服务器
第五:取得的数据返回recibuffer
def testlogin(ip,port,buf):
dllName = "SessionConnector.dll"
dllABSPath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dllName
dll = cdll.LoadLibrary(dllABSPath)
dll.Init.restype = c_bool;
ret = dll.Init();
dll.CreateSession.argtypes=[c_char_p,c_char_p]
dll.CreateSession.restype = c_int;
session_id = dll.CreateSession(ip,port);
time.sleep(2);
dll.SendSessionMsg.argtypes=[c_int,c_char_p,c_uint]
dll.CreateSession.restype = c_bool;
send_msg = buf
ret = dll.SendSessionMsg(session_id, send_msg, len(send_msg) + 1);
dll.RecvSessionMsg.argtypes=[c_int,c_char_p,c_uint,c_int]
dll.RecvSessionMsg.restype = c_bool;
recv_buf = create_string_buffer(1024);
ret = dll.RecvSessionMsg(session_id, recv_buf, 1024, 3000);
return recv_buf.value
很明显存在很多的问题。最明显的就是这个模块中,第一和第二,第三的前3个步骤,不是每个接口都必须做的事情,所有接口在测试之前干完这些事就可以了。所有这块代码必须得弄成一个类模块,再打成一个包,然后做为关键字提供给RF工具在写case的时候使用,于是就开始重点的关注了下python的类和对象,粗看的时候改写代码是这样的:
class Main_class_dll(): def __init__(self):
dllName = "SessionConnector.dll"
dllABSPath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dllName
self.dll = cdll.LoadLibrary(dllABSPath)
self.session_id='' def int_create_(self):
self.dll.Init.restype = c_bool
sign = self.dll.Init() def Create_Session(self,ip,port):
self.dll.CreateSession.argtypes=[c_char_p,c_char_p] #输入参数的格式
self.dll.CreateSession.restype = c_int; #输出参数的格式
self.session_id = self.dll.CreateSession(ip,port); def send_recv(self,buf):
time.sleep(2)
self.dll.SendSessionMsg.restype = c_bool;
self.dll.SendSessionMsg.argtypes=[c_int,c_char_p,c_uint]
ret = self.dll.SendSessionMsg(self.session_id, buf, len(buf) + 1);
self.dll.RecvSessionMsg.argtypes=[c_int,c_char_p,c_uint,c_int]
self.dll.RecvSessionMsg.restype = c_bool;
recv_buf = create_string_buffer(1024);
ret = self.dll.RecvSessionMsg(self.session_id, recv_buf, 1024, 3000); self.dll.DestroySession.restype = c_bool;
ret = self.dll.DestroySession(self.session_id); return recv_buf.value
然后在RF里调用,老是报错,调试后是发现初始化都有问题,dll也都没加载起来。后面仔细想想,确实觉得这样写是有问题的,__init__方法,表示创建的实例本身时调用的函数进行初始化用的,但是在RF内,始终就没有去创建一个类的实例,直接导入后,使用里面的函数做关键字就可以了,那就是能提供类对象,直接操作类的函数。那类对象和实例对象有什么区别呢?
类对象就是可以用类名字直接使用表示的对象,它支持两种操作,直接属性使用和实例化。对于类属性的使用,直接使用类名.属性即可。对于类方法的使用,需要实例化一个对象后,将对象名赋值给self使用,如下所示:
class test:
data = 1
def __init__(self):
self.property=0 def test2(self):
print 'hello' if __name__=='__main__':
t = test()
print test.data
print t.data
print test.test2
print t.test2()
print test.test2(t)
运行结果如下:
1
1
<unbound method test.test2>
hello
hello
那实例对象和类对象分别修改数据成员变量,会是怎么样的呢?
class test:
data = 1
def __init__(self):
self.property=0 def test2(self):
return 'hello' if __name__=='__main__':
test1= test()
test2=test() print 'test.data = ',test.data
print 'id of test.data', id(test.data)
print '*'*10 print 'test1.data = ',test1.data
print 'id of test1.data', id(test1.data)
print '*' * 10 print 'test2.data = ',test2.data
print 'id of test2.data', id(test2.data)
print '*' * 10 test1.data = 2
print 'test1.data = ', test1.data
print 'id of test1.data', id(test1.data) print 'test.data = ', test.data
print 'id of test.data', id(test.data)
print '*' * 10 print 'test2.data = ', test2.data
print 'id of test2.data', id(test2.data)
print '*' * 10 test1.__class__.data= 2 print 'test1.data = ', test1.data
print 'id of test1.data', id(test1.data)
print '*' * 10 print 'test2.data = ', test2.data
print 'id of test2.data', id(test2.data)
print '*' * 10 print 'test.data = ', test.data
print 'id of test.data', id(test.data)
print '*' * 10
运行结果如下:
test.data = 1
id of test.data 37285680
**********
test1.data = 1
id of test1.data 37285680
**********
test2.data = 1
id of test2.data 37285680
**********
test1.data = 2
id of test1.data 37285668
test.data = 1
id of test.data 37285680
**********
test2.data = 1
id of test2.data 37285680
**********
test1.data = 2
id of test1.data 37285668
**********
test2.data = 2
id of test2.data 37285668
**********
test.data = 2
id of test.data 37285668
**********
从这个例子得出一个结论:
总结 :
第一:作为test的类对象的变量 (data),每次创建一个新的实例对象,类对象变量就多一个引用指向它,通过实例对象来修改类对象的变量的取值,实际上是让实例对象
的data指向了另外一块内存变量。实例对象是类对象的一个拷贝。
第二:可以通过实例对象.__class_.data 来获取类对象的data值,改变类对象的变量的值后,相应实例的值也会发生变化。
类对象的变量在实例中实际上是只读的,任何实例都无法修改类对象变量的值(test1.data=2 实际上是让实例的变量指向了另一块内存,当再生成一个新的对象时,
值仍然还是1),通过实例对象.__class_.data可以修改类对象的属性值
然后又想到一个问题,类成员的变量,实例对象生成的时候就有么?实例成员变量,类对象直接就有么?这就需要用到vars()来测试一下:dir(object)和vars(object)是用来查看模块的attribute和properties的;其中通过help()得到官方的解释如下:
dir使用: dir([object]) -> list of strings
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes of its bases.
for any other object: its attributes, its class's attributes, and recursively the attributes of its class's base classes.
vars使用:vars([object]) -> dictionary
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
class test3:
__value1=0
value2=0 def __init__(self):
self.__value3=0 def testit(self):
pass if __name__=='__main__':
test=test3()
print 'vars(test)=',vars(test)
print 'vars(test3)=',vars(test3) print 'dir(test)=', dir(test)
print 'dir(test3)=', dir(test3)
运行结果:
vars(test)= {'_test3__value3': 0}
vars(test3)= {'__module__': '__main__', 'testit': <function testit at 0x027831B0>, '_test3__value1': 0, 'value2': 0, '__doc__': None, '__init__': <function __init__ at 0x027831F0>}
dir(test)= ['__doc__', '__init__', '__module__', '_test3__value1', '_test3__value3', 'testit', 'value2']
dir(test3)= ['__doc__', '__init__', '__module__', '_test3__value1', 'testit', 'value2']
dir:如果是一个模块对象,就是一个模块的属性;如果是一个类对象,就是类及其父类的属性;如果是其他对象,就是它本身的属性和它的类对象以及其父类的对象。只显示其属性字段,不显示其值。
vars:vars(object)等价于 object.__dict__,显示当前命名空间内的属性和值。
私有成员分:类对象的变量私有和实例对象的变量私有,对于类对象的私有成员,在实例对象生成初期,实例对象的命名空间内是不存在类对象的任何变量(不管私有或公有),实例对象是无法直接修改的,可以通过实例对象.类名.类对象的私有成员来进行访问和修改,之后命名空间内就有了该数据的引用。
明白了类对象和实例对象的不同之后,修改脚本如下所示,测试终于能跑通了~~~
class Main_class_dll():
dllName = "SessionConnector.dll" # 仅仅是定义了一个string 字符串而已
dllABSPath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dllName
dll = cdll.LoadLibrary(dllABSPath)
session_id='' def __init__(self):
pass def int_create_(self):
self.dll.Init.restype = c_bool
sign = self.dll.Init() def Do_work_connector(self,ip,port):
self.dll.CreateSession.argtypes=[c_char_p,c_char_p] #输入参数的格式
self.dll.CreateSession.restype = c_int; #输出参数的格式
self.session_id = self.dll.CreateSession(ip,port); def Do_work_send_recv(self,buf):
time.sleep(2)
self.dll.SendSessionMsg.restype = c_bool;
self.dll.SendSessionMsg.argtypes=[c_int,c_char_p,c_uint]
ret = self.dll.SendSessionMsg(self.session_id, buf, len(buf) + 1);
self.dll.RecvSessionMsg.argtypes=[c_int,c_char_p,c_uint,c_int]
self.dll.RecvSessionMsg.restype = c_bool;
recv_buf = create_string_buffer(1024);
ret = self.dll.RecvSessionMsg(self.session_id, recv_buf, 1024, 3000); self.dll.DestroySession.restype = c_bool;
ret = self.dll.DestroySession(self.session_id); return recv_buf.value def Close_Session(self):
self.dll.MainSessionClosed.argtypes = [c_int]
self.dll.MainSessionClosed.restype = None
self.dll.MainSessionClosed(self.session_id)
python—类对象和实例对象的区别的更多相关文章
- python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法
类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...
- Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象
什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...
- 理解Python中的类对象、实例对象、属性、方法
class Animal(object): # 类对象 age = 0 # 公有类属性 __like = None # 私有类属性 def __init__(self): # 魔法方法 self.na ...
- python之 类对象 类方法 实例对象 实例方法 静态方法
实例对象1. 创建的时间:使用 类名()的时候,就创建一个实例对象2. 实例属性:怎样添加 只要是一个变量能够指向这个实例对象,那么这个变量.xxxx = 111就是给其添加一个实例属性 特点: 跟着 ...
- python面向对象中类对象、实例对象、类变量、实例变量、类方法、实例方法、静态方法
1. 类对象和实例对象 Python中一切皆对象,Python类本身也是一种对象,类定义完成后,会在当前作用域中定义一个以类名为名字的命名空间.类对象具有以下两种操作: 可以通过“类名()”的方式实例 ...
- 组合,Mixin,类、类对象、实例对象
1.组合,将几个横向关系的组合在一起.所谓的组合就是将类的实例化放到新类里面,那么就将旧类组合进去了. class Turtle: def __init__(self, x): # 注意 init 前 ...
- 关于Python类属性与实例属性的讨论
标题名字有点长. 之所以想写这个文章是因为碰巧看到网上一篇关于Pyhon中类属性及实例属性区别的帖子.因为我之前也被这个问题困扰过,今天碰巧看到了这篇帖子,发现帖子的作者只是描述了现象,然后对原因的解 ...
- python 类属性和实例属性
class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...
- 【转】python类中super()和__init__()的区别
[转]python类中super()和__init__()的区别 单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(se ...
随机推荐
- 用CSS为表格添加边框
格式: <style type="text/css"> table tr td,th {border:1px solid #000;} </style>
- [Stanford 2011] 知识点小结
1.获得帮助:option+click / option+double click 2.@property里的nonatomic,表示非原子性访问,atomic是obj-c里使用的一种线程保护技术, ...
- ArcGIS API for Silverlight 调用GP服务准备---GP模型建立、发布、测试
原文:ArcGIS API for Silverlight 调用GP服务准备---GP模型建立.发布.测试 第一篇.GP降雨量等值线建模.发布及测试 在水利.气象等行业中,要在WebGIS中实现空间分 ...
- [LeetCode]题解(python):082 - Remove Duplicates from Sorted List II
题目来源 https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ Given a sorted linked list ...
- windows SVN搭建
Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: http:// ...
- asp.net操作xml
下面是xml文档内容: <content width="368" height="450" bgcolor="cccccc" load ...
- thinkPHP 接支付宝及时到账接口
支付宝及时到帐接口,现在整理以下: 1.先将支付宝提供的公共类库函数库文件防盗thinkPHP的Vender目录下建的一个alipay文件下,以便之后的调用. //四个文件我分别给他们改了下名字,因为 ...
- Change Tracking of SQLServer
1.Enable the change tracking at the database level. ALTER DATABASE AdventureWorks2008 SET CHANGE_TRA ...
- 实现简易的android 直播技术
Android 的直播,主要使用的是camera采集的数据推流到服务器上,在客户端播放camera采集的数据.采用SurfaceView+ SurfaceTexture来显示camera数据, Sur ...
- swift 异步加载图片(第三方框架ImageLoader)
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: ...