最近在对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—类对象和实例对象的区别的更多相关文章

  1. python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法

    类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...

  2. Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象

    什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...

  3. 理解Python中的类对象、实例对象、属性、方法

    class Animal(object): # 类对象 age = 0 # 公有类属性 __like = None # 私有类属性 def __init__(self): # 魔法方法 self.na ...

  4. python之 类对象 类方法 实例对象 实例方法 静态方法

    实例对象1. 创建的时间:使用 类名()的时候,就创建一个实例对象2. 实例属性:怎样添加 只要是一个变量能够指向这个实例对象,那么这个变量.xxxx = 111就是给其添加一个实例属性 特点: 跟着 ...

  5. python面向对象中类对象、实例对象、类变量、实例变量、类方法、实例方法、静态方法

    1. 类对象和实例对象 Python中一切皆对象,Python类本身也是一种对象,类定义完成后,会在当前作用域中定义一个以类名为名字的命名空间.类对象具有以下两种操作: 可以通过“类名()”的方式实例 ...

  6. 组合,Mixin,类、类对象、实例对象

    1.组合,将几个横向关系的组合在一起.所谓的组合就是将类的实例化放到新类里面,那么就将旧类组合进去了. class Turtle: def __init__(self, x): # 注意 init 前 ...

  7. 关于Python类属性与实例属性的讨论

    标题名字有点长. 之所以想写这个文章是因为碰巧看到网上一篇关于Pyhon中类属性及实例属性区别的帖子.因为我之前也被这个问题困扰过,今天碰巧看到了这篇帖子,发现帖子的作者只是描述了现象,然后对原因的解 ...

  8. python 类属性和实例属性

    class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...

  9. 【转】python类中super()和__init__()的区别

    [转]python类中super()和__init__()的区别 单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(se ...

随机推荐

  1. 20145211 《Java程序设计》实验报告四: Android开发基础

    实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android组件.布局管理器的使用: 掌握Android中事件处理机制. Android Studio安装 实 ...

  2. JMeter学习-017-java.net.SocketException: Permission denied: connect 解决方案

    前几天,有了新的接口性能测试需求,同事在添加 HTTP请求 后,运行时响应信息如下所示: java.net.SocketException: Permission denied: connect at ...

  3. rank 和 星星评级

    我们常常看到打分,如下图 这样的效果有几种方法 1.用:lt(index) /* $('dl').each(function(){ var ths = $(this); $(this).find('d ...

  4. POJ 1528问题描述

    Description From the article Number Theory in the 1994 Microsoft Encarta: ``If a, b, c are integers ...

  5. Linux命令行–更多bash shell命令(转)

    4.1.1 探查程序 ps 命令 默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户进程的进程 显示的当前进程的项目 进程号 运行在哪个终端(tty) 进程占用的CPU时间 Linux系统支 ...

  6. Android RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

  7. RabbitMQ学习总结 第一篇:理论篇

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  8. 发现EF中字段错误

    在使用EF时,报错: 对一个或多个实体的验证失败.有关详细信息,请参见“EntityValidationErrors”属性 添加一个验证方法: 代码: using System; using Syst ...

  9. js星级评分点击星级评论打分效果

    html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  10. linux bash history

    vim /etc/profile export HISTSIZE=10000 export HISTTIMEFORMAT="`whoami` : %F %T : " export ...