• python的对象和类


    1:在Python中所有的都是对象,class 是一个对象,class的实例也是一个对象。在java或者c++中,class 是不用来存放数据的,只有class的实例才存放
        数据

    1 class class1(object):
    2     pass
    1 if __name__=='__main__':
    2     test = class1()
    3     print class1
    4     print test

      class1是一个对象,print 出来的结果:<class '__main__.class1'>
     那么 test也是一个对象,test.__class__也是一个对象
     


    2:在python中所有的对象允许动态的添加属性或者方法,当类添加属性之后,类的实例同样能够访问该对象
        如果修改了类的__class__的属性或者方法,那么该类对性的实例同样也具有该类的方法或者属性

     1 class class1(object):
     2     pass
     3 
     4 if __name__=='__main__':
     5     test = class1()
     6     #print class1
     7     #print test
     8    
     9 test.__class__.newAttr=10
    10     test1 = class1()
    11     print test1.newAttr

       
        当我们通过test.__class__修改了class1类的属性之后,给class1添加了个新的属性newAttr=10
        则重新test = class1()新的实例后,新的实例拥有newAttr这个属性,
        对于添加新的方法同样如此
       


      3:每个实例都有__dict__来存放动态的属性,查看一下代码:

     1 class class1(object):
     2     pass
     3 
     4 if __name__=='__main__':
     5     test = class1()
     6     #print class1
     7     #print test
     8        
     9     test.__class__.newAttr=10
    10     test1 = class1()
    11     print test.__dict__
    12     print test.__class__.__dict__
    13     print test1.__dict__
    14     print test1.__class__.__dict__
    15     test1.newAttr2=20
    16     print test.__dict__
    17     print test.__class__.__dict__
    18     print test1.__dict__
    19     print test1.__class__.__dict__


    4:继承:当继承后,python不会像java,c++那样在子类的实例中包含父类的实例,子类的实例是个全新的对象,与父类一点关系都没有
            不会包含有父类的任何东西,继承只是在子类的__base__指向了父类在查找函数,属性的过程中会查找父类
            仅此而已,而这个父类也是class对象

    5:类里的变量不是以self,开头定义的都是类变量,相当于java,c++里的static,所有实例共享他们

    6:python为每一个对象定义了一些属性和方法
            __doc__
            __module__
            __class__
            __bases__
            __dict__


    7:python的继承
    基类 __init__ / __del__ 需显示调用
    继承方法的调用和基类声明顺序有关
    在成员名称前添加 "__" 使其成为私有成员。
    除了静态(类型)字段,我们还可以定义静态方法。

    1 class Class1:
    2     @staticmethod
    3     def test():
    4     print "static method"
    5    
    6 Class1.test()
    7 static method

               
    从设计的角度,或许更希望用属性(property)来代替字段(field)。

     1 class Class1:
     2     def __init__(self):
     3         self.__i = 1234
     4     def getI(self): return self.__i
     5     def setI(self, value): self.__i = value
     6     def delI(self): del self.__i
     7     I = property(getI, setI, delI, "Property I")
     8                  
     9 a = Class1()
    10 a.I
    11 1234
    12 a.I = 123456
    13 a.I
    14 123456
    15                 

    如果只是 readonly property,还可以用另外一种方式。
     

     1 class Class1:
     2     def __init__(self):
     3         self.__i = 1234 
     4     @property
     5     def I(self):
     6         return self.__i
     7                  
     8 a = Class1()
     9 a.I
    10 1234
    11                 

                   
    用 __getitem__ 和 __setitem__ 可以实现 C# 索引器的功能。

    class Class1:
        def __init__(self):
            self.__x = ["a", "b", "c"]
        def __getitem__(self, key):
            return self.__x[key]
        def __setitem__(self, key, value):
            self.__x[key] = value
                                
    a = Class1()
    a[1]
    'b'
    a[1] = "xxxx"
    a[1]
    'xxxx'


    8:python的多重继承
    由于python的继承主要是将几个对象建立关系,因此多重继承最重要的就是怎样在多个父类中寻找某个attribute
    python寻找attribute的顺序:  

    1. If attrname is a Python-provided attribute for objectname, return it.

    2. Check objectname.__class__.__dict__ for attrname. If it exists and is a data-descriptor, return the descriptor result. Search all bases of objectname.__class__ for the same case.

    3. Check objectname.__dict__ for attrname, and return if found. Unless objectname is a type object, in which case search its bases too. If it is a type object and a descriptor is found in the object or its bases, return the descriptor result.

    4. Check objectname.__class__.__dict__ for attrname. If it exists and is a non-data descriptor, return the descriptor result. If it exists, and is not a descriptor, just return it. If it exists and is a data descriptor, we shouldn't be here because we would have returned at point 2. Search all bases of objectname.__class__ for same case.

    5. Raise AttributeError



    9:python重载
    我们还可以通过重载 __getattr__ 和 __setattr__ 来拦截对成员的访问,需要注意的是 __getattr__ 只有在访问不存在的成员时才会被调用。

     1 class Class1:
     2     def __getattr__(self, name):
     3         print "__getattr__"
     4         return None
     5     def __setattr__(self, name, value):
     6         print "__setattr__"
     7         self.__dict__[name] = value
     8        
     9 
    10            
    11 >>> a = Class1()
    12 >>> a.x
    13 __getattr__
    14 >>> a.x = 123
    15 __setattr__
    16 >>> a.x
    17 123
    18         

    如果类型继承自 object,我们可以使用 __getattribute__ 来拦截所有(包括不存在的成员)的获取操作。
    注意在 __getattribute__ 中不要使用 "return self.__dict__[name]" 来返回结果,因为在访问 "self.__dict__" 时同样会被 __getattribute__ 拦截,从而造成无限递归形成死循环。

     1 class Class1(object):
     2     def __getattribute__(self, name):
     3          print "__getattribute__"
     4          return object.__getattribute__(self, name)
     5        
     6 >>> a = Class1()
     7 >>> a.x
     8 __getattribute__
     9        
    10 Traceback (most recent call last):
    11 File "<pyshell#3>", line 1, in <module>
    12 a.x
    13 File "<pyshell#1>", line 4, in __getattribute__
    14 return object.__getattribute__(self, name)
    15 AttributeError: 'Class1' object has no attribute 'x'
    16 >>> a.x = 123
    17 >>> a.x
    18 __getattribute__
    19 123
  • 相关阅读:
    打赏
    996315便捷扫码接口的使用方法
    openjdk ImageIO.write()时出现Invalid argument to native writeImage
    CentOS7通过rpm包升级openssh8.8
    python docx转pdf
    python生成币私钥公钥
    二叉树的非递归后序遍历算法
    STM32引脚做输入时,有开漏,浮空输入,弱上拉,弱下拉,等多种方式,如何选择????
    TLC2551驱动问题
    connot launth the modelsimaltera softwarre because you did not specify the path to the executables of the modelsimaltera softwarre
  • 原文地址:https://www.cnblogs.com/huazi/p/2491869.html
Copyright © 2020-2023  润新知