zoukankan      html  css  js  c++  java
  • python 类进阶

    一、类成员

    1、字段(属性)

    - 静态字段(类属性)

    - 普通字段(实例属性)

    静态字段可以被类直接调用,也可以被实例调用,在创建类的时候创建;

    普通字段只能被实例调用,在对象实例化的的时候创建。

    class Foo:
         city = 'Beijing' # 静态字段
         
          def __init__(self):
               name = 'lilei' # 普通字段
               age = 28       # 普通字段
    >>>print(Foo.city)  # 静态字段可以被类直接调用
    Beijing   
    
    >>>f = Foo()
    >>>print(f.city)    # 静态字段可以被实例调用
    Beijing
    >>>print(f.name)    # 普通字段只能被实例调用
    lilei

    2、方法

    -  类中的函数称为方法

    1、普通方法

    class Foo:
         def __init__(self):
              self.name = 'lilei'
              self.age    = 18
        
         def print_name(self): 
              '''
              普通方法 print_name
              每个普通方法的第一个参数是 self, 代表实例化后的对象
              '''
              print(self.name)
    >>> f = Foo() # 实例化对象
    >>> print(f.print_name) # 普通方法只有实例化后才能调用,执行普通方法
    lilei 

    2、静态方法

    class Foo:
         county = 'China'
         def __init__(self, city):
             self.city = city
    
         @staticmethod # 静态方法装饰器
         def bar(arg):        # 静态方法没有固定的第一一个参数
             '''
             静态方法不能调用静态字段和普通字段
    静态方法一般直接被类调用
    ''' print(arg)
    >>>Foo.bar('test')
    test

    3.类方法

    class Foo:
         country = 'China'
         city = 'beijing'
         def __init__(self):
             self.name = 'lilei'
             self.age = 28
          
         @classmethod   # 类方法装饰器
          def print_city(cls): # 类方法的第一个参数是cls,代表类背身
               '''
               类方法可以调用静态字段
               '''
                print(cls.city)
    >>>Foo.print_city()
    'Beijing'

    三、property

    -  将类中的方法变为一个属性,该属性的调用方法和字段一样

    class Pager:
        """
        计算分页的功能
        """
        
        def __init__(self, all_count):
            self.all_count = all_count
        
        
        @property
        def all_pager(self):
            """
            计算需要分几页,比如以每页10条为例子
            :return:
            """
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + 1
        
    p = Pager(101)
    ret = p.all_pager
    print(ret)
    class Pager:
    """
    计算分页的功能
    """
    
    def __init__(self, all_count):
        self.all_count = all_count
    
    @property       # 将一个方法变为属性
    def all_pager(self):
        """
        计算需要分几页,比如以每页10条为例子
        :return:
        """
        a1, a2 = divmod(self.all_count, 10)
        if a2 == 0:
            return a1
        else:
            return a1 + 1
    
    @all_pager.setter    # 让all_pager属性具有赋值的方法,提供一个关联方式,具体的创建变量的代码还是需要自己去写的
    def all_pager(self, value):
        print(value)
        
    @all_pager.deleter   # 让all_pager属性具有删除的方法, 将del和这个方法进行关联,具体的删除方法还是需要自己去写的
    def all_pager(self):
        print(“del all_pager”)
    
    p = Pager(101)
    ret = p.all_pager
    print(ret)
        
    p.all_pager = "100" # 给属性设置参数,会调用被装饰器@all_pager.setter装饰的方法
    del p.all_pager # 删除  会调用被装饰器all_pager.deleter 装饰的方法

    - 以函数的方式调用property

    class Pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        def f1(self):
            return 123
    
        def f2(self, value):
            pass
    
        def f3(self):
            pass
    
        foo = property(fget=f1, fset=f2, fdel=f3)  # 将foo实例化成一个属性,对foo进行调用的时候执行方法f1,对foo方法进行赋值的时候执行方法f2,对foo进行删除的时候调用方法f3
    
    p = Pager(100)
    result = p.foo
    print(result)
    
    p.foo = "aaa"
    
    del p.foo

    四、成员修饰符

    - 私有修饰符,不能在任何外部访问的区域访问,包括子类中。

      - 私有字段

        只能在内部调用,不能在外部包括子类中调用

    class Foo:
        def __init__(self, name):
            self.__name = name  # 定义一个私有的普通字段
    
        def f1(self):
            print(self.__name)
    
    class Bar(Foo):
        def f2(self):
            print(self.__name)   # 调用不到私有普通字段
    obj = Foo("lilei")
    print(obj.__name)   # 报错,私有字段只能够在本类中的方法进行调用
    obj.f1()    # 这个就是正常的

     - 私有静态字段 # 需要将一个方法变成静态方法,在静态方法中调用静态字段,然后在类外面通过调用类的静态方法,就可以访问类中的静态字段了.

      

    class Foo:
        __cc = "123"        # 定义一个私有的静态字段
    
        def __init__(self, name):
            self.__name = name  
    
        @staticmethod
        def f1():
            print(Foo.__cc)
    
    
    # print(Foo.__cc) # 这样调用会报错
    Foo.f1()  # 这样就可以了

    - 私有方法

      - 私有普通方法

    class Foo:
    
        def __init__(self, name):
            self.name = name  # 定义一个私有的普通字段
    
        def __print(self):
            print(self.name)
    
        def f1(self):
            self.__print()
    
    
    obj = Foo("aaa")
    obj.f1()  # 通过调用类中的公有方法来执行私有方法

      - 私有静态方法

    class Foo:
    
        def __init__(self, name):
            self.name = name  # 定义一个私有的普通字段
    
        @staticmethod
        def __f2(num):
            print(num)
    
        @staticmethod
        def f3(num):
            Foo.__f2(num)
    
    Foo.f3(10)

    - 私有字段的访问方法

      - 使用对象访问私有的字段或方法可以通过obj._类名私有方法 调用类中私有的字段和方法(算是后门吧)

        

    class Foo:
    
        """
        这是一个测试类
        """
    
        def __init__(self, name):
            self.name = name
            self.__age = 10
    
        def __print(self):
            print(self.name)
    
    obj = Foo("xx")
    print(obj._Foo__age)
    obj._Foo__print()

    五、 特殊成员

    - __init__ 构造方法 这个就不说了

    - __del__ 析构方法,实例释放内存前要执行的动作

    class C:
        def __init__(self, name,age):
            self.__name = name
            self.age = age
    
        def __del__(self):
            print('__del__ exec.')
    >>> c = C('lilei', 28)
    __del__ exec.          # 在释放内存时,执行了析构方法

    - __call__ 方法

      对象在被调用时调用该方法

       

    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __call__(self):
            print('__call__ function exec.')
    >>>c = C('tom', 18)
    >>>c() # 对象调用时,调用了__call__ 方法
    call function exec.

    - __str__方法

      print 对象时或者str(对象)时,调用该方法并将返回值赋值给对象。

    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return self.name
    # 调用方式1 print
    >>> c = c = C('lilei', 18)
    >>>print(c)
    lilei
    # 调用方式2 str函数
    >>> c = C('lilei', 18)
    >>> str(c)
    lilei

    - __dict__ 输出对象的字段

    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return self.name
    >>>c = C('lilei', 18)
    >>>print(c.__dict__)
    {'age': 18, 'name': 'lilei'}

    - __getitem__ 方法

       - 通过访问字典的方式访问, 调用该方法

       - 通过切片的方法访问,调用该方法

    # 通过访问字典的方式,访问对象
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __getitem__(self, item):
            print('getitem')
    
    >>>c = C('lilei', 18)
    >>>c['xxx']
    getitem
    # 通过切片的方式访问对象
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __getitem__(self, item):
            print('getitem')
            print(item.start)
            print(item.stop)
            print(item.step)
    
    >>>c = C('lilei', 18)
    >>>c[1:5:2]
    getitem
    1
    5
    2

    - __setitem__ 方法

      - 通过字典的方式赋值,调用该方法

      - 通过切片的方式赋值,调用该方法

    # 通过字典方式赋值
    
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __setitem__(self, key, value):
            print('set {} = {}'.format(key, value))
    
    
    >>>c = C('lilei', 18)
    >>>c['xxx'] = 123
    set xxx = 123
    # 通过切片的方式访问
    
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __setitem__(self, key, value):
            print('set {} = {}'.format(key, value))
            print(key.start)
            print(key.stop)
            print(key.step)
    
    >>>c = C('lilei', 18)
    >>>c[1:5:2] = 123
    set slice(1, 5, 2) = 123
    1
    5
    2

    - __delitem__方法

      - 通过del字典键的方式调用

      - 通过del切片的方式调用

    # 通过del字典的方式调用
    
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __delitem__(self, key):
            print('del {}'.format(key))
    
    >>>c = C('lilei', 18)
    >>>del c[‘xxx’]
    del xxx
    # 通过del切片的方式访问
    
    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __delitem__(self, key):
            print('del {}'.format(key))
    
    >>>c = C('lilei', 18)
    >>>del c['1:5:2']
    del slice(1, 5, 2)

    - __iter__ 对对象迭代时,调用该方法

    class C:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __iter__(self):
            yield 1
            yield 2
    
    >>>c = C('tom', 28)
    >>>for i in c:
           print(i)
    
    1
    2
  • 相关阅读:
    8.ffmpeg-基础常用知识
    7.SwrContext音频重采样使用
    6.AVCodecContext和AVCodec
    5.AVStream和AVCodecParameters
    Discuz论坛禁止匿名发贴,却出现匿名发帖或回复?找不到发帖用户,DZ如何禁止匿名发帖修改教程
    在独立服务器上通过Ubuntu 18.04+apache2+php5.6+mysql5.7+discuz!x3.4搭建的论坛实现伪静态的正确方法
    [源码] 2200套微信小程序源码
    discuz论坛更换目录后出现头像无法显示/ucenter无法进入
    discuz 您的服务器不支持 CURL,这将会导致应用无法安装。请联系您的服务商或者网站技术人员
    Discuz在服务器配置安装时出现xml_parser_create()不支持
  • 原文地址:https://www.cnblogs.com/9527chu/p/5631163.html
Copyright © 2011-2022 走看看