• python 类属性 实例属性 类方法 实例方法 静态方法(转载)


    本文是转载,纯粹是为了方便后面自己查看,建议还是看原文的:http://www.cnblogs.com/dolphin0520/archive/2013/03/29/2986924.html

    一、先来谈一下类属性和实例属性

      在前面的例子中我们接触到的就是类属性,顾名思义,类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。

    class people:
        name = 'jack'  #公有的类属性
        __age = 12     #私有的类属性
    
    p = people()
    
    print p.name             #正确
    print people.name        #正确
    print p.__age            #错误,不能在类外通过实例对象访问私有的类属性
    print people.__age       #错误,不能在类外通过类对象访问私有的类属性


    实例属性是不需要在类中显示定义的,比如:
    class people:
        name = 'jack'
    
    p = people()
    p.age =12         #实例属性
    print p.name    #正确
    print p.age     #正确
    
    print people.name    #正确
    print people.age     #错误
    在类外对类对象people进行实例化之后,产生了一个实例对象p,然后p.age = 12这句给p添加了一个实例属性age,赋值为12。这个实例属性是实例对象p所特有的,注意,类对象people并不拥有它(所以不能通过类对象来访问这个age属性)。当然还可以在实例化对象的时候给age赋值。


    class people:
        name = 'jack'
        
        #__init__()是内置的构造方法,在实例化对象时自动调用
        def __init__(self,age):
            self.age = age
    
    p = people(12)    # 构造函数初始化
    print p.name    #正确
    print p.age     #正确
    
    print people.name    #正确
    print people.age     #错误


    如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。

    class people:
        country = 'china'
        
    
    print people.country      #输出的是china
    p = people()
    print p.country           #输出的是china
    p.country = 'japan' 
    print p.country      #实例属性会屏蔽掉同名的类属性   输出的是 japan
    print people.country   #输出的是china
    del p.country    #删除实例属性
    print p.country  #因为上面一步已经删除了实例属性,现在只剩类属性了,因此输出的是china

    二、下面看一下类方法、实例方法和静态方法的区别
    类方法:是类对象所拥有的方法,需要用修饰器"@classmethod"来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以"cls"作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
    class people:
        country = 'china'
        
        #类方法,用classmethod来进行修饰
        @classmethod
        def getCountry(cls):
            return cls.country
    
    p = people()
    print p.getCountry()    #可以用过实例对象引用
    print people.getCountry()    #可以通过类对象引用

    类方法还有一个用途就是可以对类属性进行修改:

    class people:
        country = 'china'
        
        #类方法,用classmethod来进行修饰
        @classmethod
        def getCountry(cls):
            return cls.country
            
        @classmethod                       #修改类属性
        def setCountry(cls,country):
            cls.country = country
            
    
    p = people()
    print p.getCountry()    #可以用过实例对象引用
    print people.getCountry()    #可以通过类对象引用
    
    p.setCountry('japan')   
    
    print p.getCountry()   
    print people.getCountry() 

    运行结果:

      

    结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变。

    实例方法:在类中最常定义的成员方法,它至少有一个参数并且必须以实例对象作为其第一个参数,一般以名为'self'的变量作为第一个参数(当然可以以其他名称的变量作为第一个参数)。在类外实例方法只能通过实例对象去调用,不能通过其他方式去调用。

    class people:
        country = 'china'
        
        #实例方法
        def getCountry(self):
            return self.country
            
    
    p = people()
    print p.getCountry()         #正确,可以用过实例对象引用
    print people.getCountry()    #错误,不能通过类对象引用实例方法

    静态方法:需要通过修饰器"@staticmethod"来进行修饰,静态方法不需要多定义参数。

    class people:
        country = 'china'
        
        @staticmethod
        #静态方法
        def getCountry():
            return people.country
            
    
    print people.getCountry()

    对于类属性和实例属性,如果在类方法中引用某个属性,该属性必定是类属性,而如果在实例方法中引用某个属性(不作更改),并且存在同名的类属性,此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性,若实例对象没有该名称的实例属性,则引用的是类属性;如果在实例方法更改某个属性,并且存在同名的类属性,此时若实例对象有该名称的实例属性,则修改的是实例属性,若实例对象没有该名称的实例属性,则会创建一个同名称的实例属性。想要修改类属性,如果在类外,可以通过类对象修改,如果在类里面,只有在类方法中进行修改。

      从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。

  • 相关阅读:
    ajax java base64 图片储存
    计算瓶酒的数量
    Eclipse 打不开
    C# 调用百度翻译Api
    MVC API 权限控制
    C#编程语言与面向对象——委托
    C#编程语言与面向对象—— 多态
    C#编程语言与面向对象——抽象基类与接口
    C#编程语言与面向对象——继承
    动态加载及调用程序集
  • 原文地址:https://www.cnblogs.com/scodong/p/4813343.html
Copyright © 2020-2023  润新知