美文网首页
Python面向对象-类的理解

Python面向对象-类的理解

作者: Sunnky | 来源:发表于2016-12-21 15:54 被阅读0次

    类(Class)是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。

    python中,私有的属性或方法都必须前面加__(双下划线)

    首先让我们看一下Python中类的定义:

    class People:
        galaxy = 'Galactic' #类属性(公有属性)
        __star = 'Earth'    #类属性(私有属性)
        
        def __init__(self, name, age): 
            self.__name = name  #(实例属性:私有属性)
            self.age = age  #(实例属性:公有属性)
        
        #类方法
        @classmethod
        def say(cls, mess):
            print "I say %s" % mess
        
        #实例方法
        def code(self, language):
            print "I can code use %s" % language
            
        #静态方法    
        @staticmethod
        def run(velocity):
            print "I run %f km/h" % velocity
            
    

    Python中的init(self, ...)在生成对象时调用(称内置方法),self参数相当于Java中的this(可以写成其他的参数名,不过一般都写成self,便于理解),不需要显示调用(即可以不用写),系统默认执行,且支持重载,跟Java中的构造函数类似,其它内置方法还有del(self), __cmp__(), __len__()等等

    以上类中出现的概念,下面都会详细的介绍到

    python中区分类属性和实例属性

    类属性

    类属性就是类本身(类也是一个对象,所有也可以叫类对象)所拥有的属性,可以被该类的所有实例化对象所共有,在内存中只有一个副本,和Java中的静态成员变量相似。对于公有的类属性,在类外面,既可以通过==类对象本身.属性==访问,也可以通过==实例对象.属性==进行访问。

    class People:
        name = 'nanxue'
    
    p = People()    #实例化时,并不需要new
    print p.name    # nanxue
    print People.name     # nanxue
    

    注意:虽然类定义的时候,类名后紧跟了冒号(class People:),但实例化时,必须写成 instance = className() 的形式,如果类中有构造函数的重载,则必须写成重载的形式,比如这样

    class People:
        name = 'nanxue'
        
        def __init__(self,age):
            self.age = age
            
    p = People(20)    #实例化时,并不需要new
    p = People()      #error (TypeError: __init__() takes exactly 2 arguments (1 given))
    

    实际上Python2.2以后,规定所有类都继承自object基类,所以其实也可以这么写 class People(object):

    而私有的类属性不管是类对象还是实例对象,在类外面都不能访问,例如下面的访问形式就会出错

    class People:
        __name = 'nanxue'
    
    p = People()
    print p.__name    # error(AttributeError: class People has no attribute '__name')
    print People.__name     # error(AttributeError: People instance has no attribute '__name')
    

    实例属性

    而实例属性,只能通过实例对象访问(类对象访问不到,见第一种),实例属性既可以在初始化的过程定义(init函数中通过self.属性),也可以在实例化后动态的添加(此时,该属性为这个实例所特有)

    • 第一种
    class People:
        name = 'nanxue'
    
        def __init__(self,age):
            self.age = age
    
    p = People(12)
    print p.name    # nanxue
    print p.age     # 12
    
    print People.age  #error(AttributeError: class People has no attribute 'age')
    
    
    • 第二种
    class People:
        name = 'nanxue'
        
    p = People()
    p.age = 12
    
    print p.name    # nanxue
    print p.age     # 12
    
    pp = People()
    print pp.age    #error(AttributeError: People instance has no attribute 'age')
    
    

    与类属性相同,在初始化函数中定义的私有实例属性在类外面是访问不到的,但是通过动态添加的私有属性可以访问的到

    class People:
        name = 'nanxue'
       
        def __init__(self,age):
            self.__age = age
        
    p = People(20)
    print p.name    # nanxue
    print p.__age   # error(AttributeError: People instance has no attribute '__age')
    
    p.__sex = 2
    print p.__sex   # 2
    
    

    此时,还存在一种情况,就是在类中定义了一个类属性,实例化后也动态添加一个同名属性,会怎么样呢?,会覆盖吗?

    class People:
        name = 'nanxue'
       
        def __init__(self,age):
            self.age = age
        
    p = People(20)
    print p.name    # nanxue
    print p.age     # 20
    
    #同名属性
    p.age = 50
    print p.age     # 50
    
    p.name = 'aaa'
    print p.name       # aaa
    print People.name  # nanxue
    
    del p.name
    print p.name    # nanxue
    
    

    可以看到,实例对象会产生一个同名的实例属性,强制屏蔽掉类属性,类属性还是原来的值,如果删除掉实例属性,则恢复为类属性,因此要修改类属性的值,需通过类对象修改

    class People:
        name = 'nanxue'
        
    p = People()
    print p.name    # nanxue
    
    #同名属性
    p.name = 'aaa'
    print p.name     # aaa
    
    #新的实例对象
    pp = People()
    print pp.name    # nanxue
    
    #修改类属性
    People.name = 'bbb'
    
    print p.name     # aaa
    print pp.name    # bbb
    

    方法的区别

    实例方法

    顾名思义,为该类的实例所有,不能通过类对象引用实例方法,至少有一个参数且必须为实例对象,也必须作为该方法的第一个参数

    class People:
        name = 'nanxue'
        
        #实例方法
        def code(self):
            return self.name
            
    p = People()
    
    print p.code()      # nanxue
    print Peopel.code() # error(unbound method code() must be called with People instance as first argument (got nothing instead))
    

    当同时存在同名的类属性与实例属性时,实例属性优先级更高

    类方法

    方法前需加修饰符@classmethod,实例对象与类对象都可以引用,第一个参数必须是类对象,一般写作cls

    class People:
        name = 'nanxue'
        
        #类方法
        @classmethod
        def eat(cls):
            return cls.name
            
    p = People()
    
    print p.eat()      # nanxue
    print People.eat() # nanxue
    

    类方法可对类属性进行修改

    class People:
        name = 'nanxue'
        
        #类方法
        @classmethod
        def setName(cls, name):
            cls.name = name
            
        @classmethod    
        def getName(cls):
    return cls.name
            
    p = People()
    
    print p.getName()        # nanxue
    print People.getName()   # nanxue
    
    p.setName('xiaonan')
    #People.setName('xiaonan')
    
    print p.getName()        #xiaonan
    print People.getName()   #xiaonan
    

    静态方法

    静态方法前需要加修饰符@staticmethod,不需要额外定义参数

    class People:
        name = 'nanxue'
        
        #静态方法
        @staticmethod
        def getStaticName():
            return People.name
            
    p = People()
    
    print p.getSaticName()        # error(People instance has no attribute 'getSaticName')
    print People.getSaticName()   # nanxue
    
    

    相关文章

      网友评论

          本文标题:Python面向对象-类的理解

          本文链接:https://www.haomeiwen.com/subject/eauqvttx.html