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
posted on 2019-07-15 22:04  ShenQiang  阅读(140)  评论(0编辑  收藏  举报