zoukankan      html  css  js  c++  java
  • Python -- 面向对象:类的成员

    类大致分为两块区域:如下图

    # 每个区域详细划分:
    class A:
        
        name = 'Agoni'  # 静态变量
        _password = '123456xxx'   # 私有静态变量
        
        def __init__(self,name,age):
            self.name = name  # 对象属性
            self.__age = age  # 私有静态属性
            
        def fucn1(self):  #	 普通方法
            pass
        
        def __func(self): #  私有方法
            pass
        
        @classmethod    # 类方法
        def classs_func(cls):   # 定义类方法,至少有一个cls参数
            print('类方法')
        
        @staticmethod   # 静态方法
        def static_func(): # 定义静态方法,无默认参数
            print('静态方法')
            
        @property   # 属性
        def prop(self):
            pass
        
    # 所有的私有成员,只能在类内部使用,不能在类的外部以及派生类中使用
    # 公有成员在类的任何地方都能访问
    

    方法包括:普通方法,静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同.

    实例方法:

    • 定义:第一个参数必须是实例对象,该参数名一般约定为 'self' ,通过它来传递实例的属性和方法(也可以传递类的属性和方法)
    • 调用:只能由实例对象调用

    类方法:

    • 定义:使用装饰器@classmethod 第一个参数必须是当前类对象,该参数名一般约定为 ' cls ',通过它来传递类的属性和方法(不能传实例的属性和方法)
    • 调用: 实例对象和类都可以调用

    静态方法

    • 定义:使用装饰器@staticmethod 参数随意,没有 self cls 参数,但是方法体重不能使用类和实例的任何属性和方法.
    • 调用: 实例对象和类对象都可以调用

    双下方法:(后面会讲到)

    • 定义: 双下方法是特殊方法,世界时期提供的由双下划线加方法名加双下划线__方法名__的具有特殊意义的方法,双下方法主要是Python源码程序员使用的.

      我们在开发中尽量不要使用双下划线方法.深入研究双下划线方法,有助于阅读源码

    • 调用:不同的双下方法有不同的出发方式.


    7.5.1 类方法

    # 类方法举例说明
    class A:
        num = 1
        def func(self):
            print('实例方法')
        
        @classmethod   # 类方法: 由类名直接调用的方法,自动将类名传给 cls
        def c__func(cls):
            print('类方法')
            print(cls.num)  # 通过类查看类中的属性
            o = cls()       # cls是A类,类名加括号实例化A
            
    obj = A()
    A.func(obj)  # 通过类名调用类中的实例方法,要给self传参数
    A.c_func()   # 通过类名调用类中的类方法
    obj.c_func() # 对象也可以调用类的方法,但是会自动将类名传给cls
    
    # 例题 定义一个学生类,统计学生的个数
    class Student:
        num = 0
        def __init__(self,name):
            self.name = name
            self.count()
            
        @classmethod
        def count(cls):
            cls.num += 1
            
        @classmethod
        def addNum(cls):
            return cls.num
            
    s1 = Student('alex')
    s2 = Student('alex')
    s3 = Student('alex')
    print(Student.addNum())
    

    7.5.2 静态方法

    # 静态方法:不依赖与类和对象,就是一个普通的函数  类名和对象都可以调用,不需要传参
    
    class A:
    
        def func(self):
            print(111)
    
        @classmethod
        def a_func(cls):
            pass
    
        @staticmethod
        def s_func():
            print('静态方法')
    
    A.s_func()
    obj = A()
    obj.s_func()
    
    # 举例
    import time
    class TimeTest:
        def __init__(self,hour,minute,second):
            self.hour = hour
            self.minute = minute
            self.second = second
    
        def func(self):
            pass
        
        @staticmethod
        def show_time():
            return time.strftime("%H:%M:%S",time.localtime())
        
    print(TimeTest.show_time())
    obj = TimeTest(1,20,30)
    obj.showTime()
    

    7.5.3 属性

    以bmi为例,测定人体体脂

    class Bmi:
        
        def __init__(self,name,height,weight):
            self.name = name 
            self.height = heiget
            self.weight = weight
            
        @property
        def bim(self):
            return self.weight/self.height**2
        
    b = Bim('Agoni',1.75,65)
    print(b.bim)   # 调用属性时,不需要加()
    

    为什么要用property

    将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

    由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

    class Foo:
        def __init__(self,name):
            self.name = name
        @property
        def aaa(self):
            print('get的时候运行我')
            
        @aaa.setter
        def aaa(self,v):
            print(v) # 123
            print('修改的时候运行我')
            
        @aaa.deleter
        def aaa(self):
            print('删除的时候运行我')
            
    obj = Fpp('Agoni')
    obj.aaa   # get的时候运行我
    obj.aaa = '123'  # 修改的时候运行我
    print(Foo.aaa)  # <property object at 0x00000137E3C578B8>
    del obj.aaa  # 删除的时候运行我
    
    # 设置属性的另一种写法
    class Foo:
        def get_aaa(self):
            print('get的时候运行我啊')
    
        def set_AAA(self,value):
            print('set的时候运行我啊')
    
        def delete_AAA(self):
            print('delete的时候运行我啊')
            
        bbb = property(get_aaa,set_aaa,delete_aaa) # 内置property三个参数与get,set,delete一一对应
    
    f1 = Foo()
    f1.bbb
    f1.bbb = 'aaa'
    def f1.bbb
    

    7.5.4 isinstace与issubclass

    isinstace(obj,N) 判断obj对象是由N类(N类的派生类)实例化的对象,返回True

    class A:
        pass
    class B(A):
        pass
    class C(B):
        pass
    
    obj = B()
    
    print(isinstance(obj,B))  # True
    print(isinstance(obj,A))  # True
    print(isinstance(obj,C))  # False
    

    issubclass(M,N) 判断M类是N类的子孙类

    class A:
        pass
    
    class B(A):
        pass
    
    class C(B):
        pass
    
    print(issubclass(C, B))  # True
    print(issubclass(C, A))  # True
    

    7.5.5 type 元类

    type到底是什么?

    type元类,Python中一切皆对象,一个类也是一个对象.name这个(类)对象肯定是由类实例化出来的,Python中自己创建的所有类,以及大部分 list str 等这些类,都是从type元类实例化得来的 .

    Python中继承object类都是新式类

    object也是有type元类实例化得来的

    s = 'affjkl'
    l = [1,2,3]
    print(type(s))  # 判断的是对象从属于哪个类
    print(type(l))
    <class 'str'>
    <class 'list'>
    
    class A:
        pass
    print(type(A))  # <class 'type'>  
    
    from collections import Iterable
    from collections import Iterator
    print("__init__" in dir(s))  True
    print(isinstance(s,Iterable))  True
    
  • 相关阅读:
    POJ 1001 Exponentiation
    POJ 2105 IP Address
    条款1:视C++为一个语言联邦
    条款2:尽量使用const ,enum,inline替换define
    走台阶问题
    Oracle之分页问题
    Oracle之子查询:Top-N问题
    Facade——外观模式
    PROXY——代理模式
    C++ 内联函数
  • 原文地址:https://www.cnblogs.com/Agoni-7/p/11191865.html
Copyright © 2011-2022 走看看