zoukankan      html  css  js  c++  java
  • Python面向对象进阶

    静态方法

    • 静态方法只是名义上归类管理, 实际上在静态方法里访问不了类或实例中的任何属性.
    • 静态方法作用:
      • 把一个方法变成静态方法, 相当于切断了它和类的关联, 不会自动传self. 就是一个函数.
        • a. 创建方法时不传入参数self.
        • b. 若一定要传入参数, 调用该方法时需要把实例化对象传给自己, 才能执行.
      • 该方法必须通过类名.方法()来调用.
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    """
    静态方法:
        静态方法只是名义上归类管理, 实际上在静态方法里访问不了类或实例中的任何属性.
    静态方法的作用:
    1. 把一个方法变成静态方法, 相当于切断了它和类的关联, 不会自动传self. 就是一个函数.
        a. 创建方法时不传入参数self.
        b. 若一定要传入参数, 调用该方法时需要把实例化对象传给自己, 才能执行.
    2. 该方法必须通过类名.方法()来调用.
    """
    
    
    class Dog(object):
        def __init__(self, name):
            self.name = name
    
        @staticmethod
        def eat():  # TODO 这样如果方法需要参数时岂不是不太方便?
            print("a is eating")
    
        @staticmethod
        def eat(self, food):  # 在调用该方法时, 必须把实例传给自己, 不会自动传入self.即 d.eat(d, "包子")
            print("%s is eating %s" %(self.name, food))
    
    
    d = Dog("ChenRongHua")
    d.eat("包子")
    静态方法

    类方法

    • 只能访问类变量(全局变量), 不能访问实例变量
    • """
      类方法:
          只能访问类变量(全局变量), 不能访问实例变量
      """
      class Dog(object):
          n = 333
          def __init__(self, name):
              self.name = name
      
          @classmethod
          def eat(self):  # 在调用该方法时, 必须把实例传给自己, 不会自动传入self.即 d.eat(d, "包子")
              print("%s is eating %s" %(self.n, 'dd'))
      
      
      d = Dog("ChenRongHua")
      d.eat()
      类方法

    属性方法

    • 把一个方法变成一个静态属性. 调用该方法时不能加(), 要像调用一个变量时直接实例化对象名.方法名.
    • 调用该方法时不能传参数(因为没有了())
    • 可以赋值. 
      • 需要再写一个同名函数(这个函数必须放在注释为property函数的下面.), 并加注释@方法名.setter. (有点像java中私有变量的set方法)
      • 实例化后给eat赋值
    • 要删掉该属性, 需要再写一个同名方法.注释是@方法名.deleter.
    • """
      属性方法:
          1. 把一个方法变成一个静态属性. 调用该方法时不能加(), 要像调用一个变量时直接实例化对象名.方法名.
          2. 调用该方法时不能传参数(因为没有了())
          3. 可以赋值. 
              a. 需要再写一个同名函数(这个函数必须放在注释为property函数的下面.), 并加注释@方法名.setter. (有点像java中私有变量的set方法)
              b. 实例化后给eat赋值
          4. 要删掉该属性, 需要再写一个同名方法.注释是@方法名.deleter.
      """
      class Dog(object):
          def __init__(self, name):
              self.name = name
              self.__food = None
      
          @property  # 把一个方法变成一个静态属性
          def eat(self):  # 在调用该方法时, 必须把实例传给自己, 不会自动传入self.即 d.eat(d, "包子")
              print("%s is eating %s" %(self.name, self.__food))
      
          @eat.setter  # 此同名方法必须写在上一个eat()方法下面. 修改一个属性.
          def eat(self, food):
              print("set to food: %s" % food)
              self.__food = food
      
          @eat.deleter  # 删除一个属性.
          def eat(self):
              del self.__food
              print("删完了")
      
      
      d = Dog("ChenRongHua")
      # d.eat()  # 返回'NoneType' object is not callable
      d.eat  # 返回ChenRongHua is eating dd
      d.eat = "包子"  # 必须有@eat.setter方法, 才能这样赋值, 否则报错.
      d.eat  # 返回ChenRongHua is eating 包子
      属性方法

    类的特殊成员方法

    • __doc__
      • 表示类的描述信息. 
      • 若类的下面写有注释, 用print方法, 可以把类的描述信息打印出来 
    class Dog(object):
        """
        这是一个描述信息
        """
    
    
    print Dog.__doc__  # 返回"  这是一个描述信息"
    __doc__
    • __module__
      • 表示当前操作的对象在哪个模块
    • __class__
      • 表示当前操作的对象的类是什么
    • __init__
      • 构造方法, 通过类创建对象时, 自动触发执行
    • __del__
      • 析构方法, 当对象在内存中被释放时, 自动触发执行
      • 注: 此方法一般无须定义, 因为python是一门高级语言, 程序员在使用时无需关心内存的分配和释放, 因为此工作都是交给python解释器来执行, 所以, 析构函数的调用是由解释器在进行垃圾回收时自动触发执行的.
    • __call__
      • 对象后面加括号 , 触发执行
      • 注: 构造方法的执行时由创建对象触发的, 即: 对象 = 类名(); 而对于__call__方法的执行时由对象后加括号触发的, 即: 对象()  或 类().
    • __dict__
      • 查看类或对象中的所有成员
        • 通过类来调用: 打印类里的所有属性, 不包括实例属性
        • 通过对象调用, 打印所有实例属性, 不包括类属性
    • __str__
      • 如果一个类中定义了__str__方法, 那么在打印对象时, 默认输出该方法的返回值.
    • __getitem__,  __setitem__,  __delitem__
      • 用于索引操作, 如字典. 以上分别表示获取, 设置, 删除数据 (类似java中的set, get方法)
      • 可以实现把字典封装成一个实例, 而且用户不能随意删除其中属性(key)
      • #!/usr/bin/python
        # -*- coding: utf-8 -*-
        
        
        # 可以封装一个类, 让用户以字典的形式访问, 并且可以通过代码来控制是不是可以删除/修改字典, 用户端则删不掉.
        class Foo(object):
            def __init__(self):
                self.data = {}
        
            def __getitem__(self, key):
                print('__getitem__', key)
                return self.data.get(key)  # 没有这一句直接打印print(obj['name'])会返回None. 要加上这一句, 才能返回'name'对应的value值.
        
            def __setitem__(self, key, value):
                print('__setitem__', key, value)
                self.data[key] = value
        
            def __delitem__(self, key):
                print('__delitem__', key)
        
        
        obj = Foo()
        obj['name'] = 'Jack'  # 自动触发执行__setitem__
        result = obj['k1']  # 自动触发执行__getitem__
        obj['k2'] = 'alex'  # 自动触发执行__setitem__
        del obj['k1']
        
        print(obj.data)  # 返回{'name': 'Jack', 'k2': 'alex'}. 把实例变成字典
        print(obj['name'])
        把类封装成字典
    • __new__ __metaclass__
    • # __new__ /__metchclass__
      class Foo(object):
          def __init__(self, name):
              self.name = name
      
      
      f = Foo("alex")
      print(type(f))  # 返回<class '__main__.Foo'>, 表示: f对象由Foo类创建
      print(type(Foo))  # 返回<class 'type'>, 表示: Foo类对象由type类创建
      """
      所以, f对象是Foo类的一个实例, Foo类对象是type类的一个实例. 即: Foo类对象, 是通过type类的构造方法创建.
      那么, 创建类就可以有两种方式:
      a. 普通方式
      b. 特殊方式 (类是由实例化type产生 )
      """
      
      # 普通方式创建类
      class Foo(object):
          def func(self):
              print('hello world')
      
      
      # 特殊方式创建类
      def func(self):
          print('hello world')
      
      def __init__(self, name,age):
          self.name = name
          self.age = age
      
      
      Foo = type('Foo', (object,), {'talk': func, '__init__': __init__})
      # type 第一个参数: 类名
      # type 第二个参数: 当前类的基类 (可以不写, 只留下())
      # type 第三个参数: 类的成员 (当前类有哪些方法. {'func': func} 可以写为{'talk': func}, 这个字典的key是当前类的成员方法名.)
      f = Foo("alex", 22)  # 实例化当前类Foo
      f.talk()  # 调用当前类Foo的成员方法talk()
      
      
      """
      类默认是由type类实例化产生, type类如何实现创建类? 类又如何创建对象?
      类中有一个属性 __metaclass__, 用来表示该类由谁来实例化创建,所以可以为__metaclass__设置一个type类的派生类, 从而查看类的创建过程.
      
      类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__
      metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好
      """
      类的创建
    • # python2.7的底层创建类方法
      class MyType(type):
          def __init__(self, *args, **kwargs):
              print("Mytype __init__", *args, **kwargs)
      
          def __call__(self, *args, **kwargs):
              print("Mytype __call__", *args, **kwargs)
              obj = self.__new__(self)
              print("obj ",obj,*args, **kwargs)
              print(self)
              self.__init__(obj,*args, **kwargs)
              return obj
      
          def __new__(cls, *args, **kwargs):
              print("Mytype __new__",*args,**kwargs)
              return type.__new__(cls, *args, **kwargs)
      
      print('here...')
      
      
      class Foo(object, metaclass=MyType):
          def __init__(self, name):
              self.name = name
      
              print("Foo __init__")
      
          def __new__(cls, *args, **kwargs):  # 通过new来实例化, new方法调用了__init__方法.
              print("Foo __new__",cls, *args, **kwargs)
              return object.__new__(cls)  # 重写__new__方法的话要继承父类的__new__方法, 才能创建实例.cls相当于Foo.
      
      
      f = Foo("Alex")
      print("f", f)
      print("fname", f.name)
      python2.7底层创建类的过程

     alex博客: http://www.cnblogs.com/alex3714/articles/5213184.html

  • 相关阅读:
    国外物联网平台(8):Telit
    国外物联网平台(7):FogHorn
    国外物联网平台(6):Electric Imp
    国外物联网平台(5):Exosite Murano
    国外物联网平台(4):Ayla Networks
    国内物联网平台(8):中移物联网开放平台OneNet
    Backbone入门讲解
    underscore.js库的浅析
    Backbone框架浅析
    Handlebars模板库浅析
  • 原文地址:https://www.cnblogs.com/cheese320/p/9206968.html
Copyright © 2011-2022 走看看