zoukankan      html  css  js  c++  java
  • python 简单谈谈“类”

    文章出处:http://www.cnblogs.com/winstic/,请保留此连接

    面向对象是python语言的一大特色,而类又是面向对象编程的核心


    先来一段关于类的声明:

    class myClass(object):            # 继承object
            """It's my first class defined """    # 文档字符串
            version = 1.0                # 静态成员
            testlist = [1, 2, 3]
            def __init__(self, nm = "john"):
                """constructor"""
                self.name = nm
            def showname(self):
                """display name"""
                print "your name is: ", self.name
            def showversion(self):
                """display version"""
                print "The version is: ", self.version

    在类中声明的静态变量(也叫类属性)version、testlist将被所有实例及类的方法show*所共享

    在类的定义中又一个很明显的特点,每个函数都有一个参数self;什么事self呢?我们可以联想一下C++中的this指针,没错她们有类似的功能,在python中self是类实例的引用,请记住是类实例的引用而不是类本身,那么我想引用实际的类怎么办,当然没问题,可以使用self.__class__


    __init__()

      这个函数很特殊,我们知道前后带有双下划线的表示python中的特殊方法,那么他有什么特殊呢,很快可以联想到构造函数(注意有区别哦)
     
      在类中经常会看到这样的方法,可以被当成构造函数,但又不同于其他语言的构造函数,它并不创建对象实例 ,仅仅只是对象创建后执行的第一个方法,主要目的是完成一些必要的初始化工作;
          一般都会有一个系统默认的__init__(),什么都不做,
           我们在__init()__方法中定义的变量,但这个变量只在类实例中存在,并不是实际类本身的一部分

    类实例修改属性值?

      每个类实例只能修改自己的属性值,可以说在多个类实例中是互不影响的,但这有一个前提:该属性值必须是不可变对象(为什么?请继续看...)

      

      虽然可以通过对象改变自己的属性值,但当您这么做的时候,请擦亮您的火眼金金,看清类属性是可变还是不可变的类型;当然如果您要改变类属性时可以使用类名.属性名 = ××××来实现;下面将简单分析不可变对象和可变对象在属性值改变情况下的区别:

    >>> # 对不可变对象(number)操作,实例间互不影响
    >>> test1 = myClass()
    >>> test2 = myClass()
    >>> test1.version = 2.0
    >>> test1.showversion()
    The version is:  2.0
    >>> test2.showversion()
    The version is:  1.0
    >>> # 对可变对象(list)操作时,实例间同步更新
    >>> test1.testlist[0] = 10
    >>> test1.testlist
    [10, 2, 3]
    >>> test2.testlist
    [10, 2, 3]
    • 原因分析:

        当改变类属性时,如果属性是immutable的,该属性会被复制出一个副本,存放在当前对象__dict__中;而原始类本身对应的值并没有改变。

    >>> test1.__dict__
    {'version': 2.0, 'name': 'john'}
    >>> test1.__class__.version
    1.0
    >>> test1.__class__.__dict__
    dict_proxy({'__module__': '__main__', 'version': 1.0, '__init__': <function __init__ at 0x025FFAB0>, '__dict__': <attribute '__dict__' of 'myClass' objects>, '__weakref__': <attribute '__weakref__' of 'myClass' objects>, 'showversion': <function showversion at 0x025FFB30>, 'testlist': [10, 2, 3], '__doc__': "It's my first class defined ", 'showname': <function showname at 0x025FFAF0>})

        而如果类属性值是可变的(mutable),因为还是在原内存地址中操作,并没有产生相应的副本,同时该值一旦改变会直接更改原始类中的对应属性值,进而影响其  他对类实例

    >>> test1.testlist
    [10, 2, 3]
    >>> test1.__class__.testlist
    [10, 2, 3]
    >>> test2.testlist
    [10, 2, 3]

    所有当我们通过类实例更改类属性值时,要特别注意的是:看清类属性对象是否可变(mutable/immutable),以免产生不必要的错误。

  • 相关阅读:
    安卓API首页
    安卓开发学习1
    Unity3D安卓交互
    跨天查询,少一天的问题
    COALESCE关键字的使用
    Map构造器模式 map builder pattern
    Linux服务器端使用tcpdump抓redis报文
    Java Unsigned Bytes
    JAVA与c#中byte取值范围的差异
    jack反序列化自定义字段绑定,报错:can only instantiate non-static inner class by using default, no-argument constructor
  • 原文地址:https://www.cnblogs.com/winstic/p/4032296.html
Copyright © 2011-2022 走看看