码迷,mamicode.com
首页 > 编程语言 > 详细

python—类对象和实例对象的区别

时间:2016-04-21 20:23:44      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

      最近在对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—类对象和实例对象的区别

标签:

原文地址:http://www.cnblogs.com/loleina/p/5409084.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!