一 .   绑定方法与非绑定方法 :

  类中定义函数分为两大类 :

    1.  绑定方法 :

      特殊之处 : 绑定给谁就应该由谁来调用, 谁来调用就会将谁当做第一个参数自动传入

      绑定给对象的方法 :在类中定义函数没有被任何装饰器修饰的情况下,默认就是绑定对象的

      绑定给类的方法 : 为类中定义函数添加一个装饰器classmethod, 就是绑定类的

 

    2. 非绑定方法 :

      特殊之处 : 非绑定方法就是一个普通的函数.

      既不与类绑定又不与对象绑定意味着类与对象都可以调用,但是无论谁来调用都是一个普通

      函数, 没有自动传值的效果.

      非绑定方法 : 为类中定义函数添加一个装饰器,staticmethod.就是非绑定方法.

      

    3. 两种方法的区别就是 : 是否会自动传值.

 

    

  示例 :

    class Foo:

      def func1(self):

        print('func1',self)

      

      @classmethod

      def func2(cls):

        print('func2',cls)

 

      @staticmethod

      def func3(x,y):

        print('func3',x,y)

 

    obj = Foo()

    # 绑定给对象的方法

    # 绑定给对象的, 就应该由对象来调.

    obj.func1()

    print(obj)

 

    # 绑定给对象的方法,类也可以调用,但是类调用就是一个普通函数,没有自动传值的效果

    print(obj.func1)

    print(Foo.func1)

    Foo.func1(obj)

 

    # 绑定给类的方法

    # 绑定给类的,就应该由类来调用

    print(Foo.func2)

    print(obj.func2)

    Foo.func2()

    obj.func2()

 

    # 非绑定方法.

    print(obj.func3)

    print(Foo.func3)

 

    obj.func3(1.2)

    Foo.func3(1.2)

 

 

  示例:

    #绑定 与 非绑定的使用场景示范

 

    class MySQL:

      def   __init__(self,ip,port):

        self.ip = ip        # 参数写成self就等于写活了.谁都能调用

        self.port = port

        

      def   tell_info(self):

        print('%s:%s' %(self.ip , self.port))

      

      @classmethod    # 用配置文件里的数据, 可以把参数写成cls.用只给类名调用的装饰器来写

      def   from_conf(cls):

        return  cls(settings.IP, settings.PORT)

 

      @staticmethod

      def   create_id():    # 不需要类名参数,也不需要对象参数, 就可以用这个装饰器来写, 不能不写

        import  uuid       参数, 不然会默认为参数是对象,就会报错.   

        return  uuid.uuid4()

 

    obj = MySQL('1.1.1.1',3306)

    obj.tell_info()

 

    总结 : 装饰器的使用是要看函数的代码是怎样的,需要什么用什么.

 

 

二 .  反射 :

  反射指的是通过字符串来操作属性 :

 

  示例:

    class Foo:

      def  __init__(self,name,age)

        self.name = name

        self.age = age

    

      def  tell_info(self):

        print('%s:%s' %(self.name,self.age))

 

    obj = Foo('egon' , 18)

    

  # hasattr 

    print (hasattr(obj,(逗号)'name'))   # 查看有没有这个属性 返回的是一个布尔值  等于 obj.name

 

  # getattr

    res = getattr(obj,'name')    #获取一属性  等于 obj.name

 

  # setattr

    setattr(obj,'age',38)   # 修改一个属性, 没有这个值就添加上这个值

 

  # delattr

    delattr(obj,'name')   # 删除一个属性, 没有这个属性就报错

 

 

 

三. 面向对象高级内置方法 之 __str__ :

  首先补充两个内置函数,

  1. isinstance

      print (isinstance([],list))  # 等于 type([]) is  list  

    判断一个对象是否属于另一个类的对象.

 

  2,  issubclass

    class Foo:

      pass

    class Bar(Foo):

      pass

    print(issubclass(Bar,Foo))

    判断一个类是不是另一个类的子类

 

  

  __str__ : 会在对象被打印时自动触发. 然后将返回值当做打印结果.

    class  People:

      def __ init __ (self,name,age)

        self.name = name

        self.age = age

 

      def  __str__(self):

        print('===>')    #这里不能加self. 不然会无限递归下去,就会报错

        return   '<%s:%s>'   %(slef.name,self.age)

    

    peo = People('name',18)

    print(peo)   # 等于打印了 print(peo.__str__())

       

 

    注意 : l = list([1,2,3])

        print(l)

      其实list 下面也有__str__的方法.不仅list.很多常用的内置函数都有

 

 

  __del__:   会在对象被删除时自动触发执行,  用来在对象被删除前回收系统资源,

    class  Foo:

      def  __del__(self):

        print('===>')

 

    obj = Foo()

    del obj

    print('其他代码...')

 

  __del__在什么时候使用?

    示例:

      class  Bar:

        def  __init__(self,x,y,filepath)

          self.x = x

          self.y = y

          self.f = open(filepath 'rt' , encoding = 'utf-8') 

    

        def __del__(self):

          self.f.close()     # 在del里写回收系统资源的代码

 

      obj = Bar(10,20)

      del  obj

 

    程序结束时会自动删除obj , obj的值也会被删除, 但是不会删除filepath 的数据. 这个时候就可以在类里

    定义上 __del__的函数属性.

 

posted on 2018-10-25 17:05  海贼王。  阅读(169)  评论(0编辑  收藏  举报