python与面向对象2(类变量、__slots__属性、类方法、静态方法)

类用来规范对象的属性和行为,类是对象产生的“生产指标书”,对象是根据类的指标下的产物

_ init_(self):函数中的self是一个空对象,等到init函数执行完成后,将这个self对象进行初始化,然后返回回去给其他的变量进行绑定。
_ del_(self):析构函数不需要传递任何参数,用来清理除对象以外的外部资源(如打开的文件)

一切皆对象,包括我们自己写的类,也是一个对象

一、类变量(c++中为静态成员变量)
上一篇文章中提到的__dict__ 以及__class__属性都是属于示例/对象的属性
什么是类变量:
类变量是类的属性,属于类,不属于此类创建的实例
说明:
为变量,可以通过该类直接访问
类变量可以通过此类的实例直接访问
类变量可以通过此类的对象 __class__属性间接访问
类变量通常来统计所有对象信息

(实际上c++中对象的属性封装在类中,直接定义好,而python是在初始化函数中才定义好的)
(而python中的类变量,又和中得静态变量类似)

示例:说明类变量的使用

class Human:
    count = 0  #类变量,记录生成了多少个对象

print(Human.count)
h1 = Human()
print(h1.count)  #通过对象来访问
Human.count = 1  #修改绑定关系,将类的变量count改为2
h1.count = 2  # 这是给h1对象中创建这个属性
print(Human.count)
#如果对象想修改类变量的值,只能通过__class__来修改
h1.__class__.count = 9
print(Human.count)

执行结果:
0
0
1
9

示例:类变量用在init函数中

class Human:
    count = 0  #类变量,记录生成了多少个对象
    def __init__(self,n):
        self.name = n
        # count + =1  这样不可以
        #Human.count +=1  这样可以
        self.__class__.count += 1  #每次生成一个对象 count+1
    def __del__(self):
        self.__class__.count -= 1 #每次销毁一个对象 count-1


print("当前的对象个数为: ",Human.count)
h1 = Human("张飞")
h2 = Human("李白")
print("当前的对象个数为: ",Human.count)
del h2
print("当前的对象个数为: ",Human.count)

执行结果:
当前的对象个数为:  0
当前的对象个数为:  2
当前的对象个数为:  1

二:类的__slots__属性
作用:
限定一个类创建实例只能有固定的属性(实例变量)
说明:
__slots__属性是一个列表,列表的值是字符串
含有__slots__属性的类所创建的对象没有__dict__字典

示例:__slots__属性来限定对象的属性,不允许私自修改种类和个数

class Student:
    def __init__(self,n,a):
        self.name = n
        self.age = a

s1 =Student("小张",10)
s1.Age = 20   #可以吗    可以
#有时我们希望我们的对象只有name和age属性,不希望有其他的属性
#可以在定义类时写成下面的格式

class Student:
    __slots__ = ['name','age']    
     #告诉解释执行器,我这个类实例的对象只有这两个属性,如果添加,会报错
    def __init__(self,n,a):
        self.name = n
        self.age = a

我们在类中添加上对应__slots__属性后,再来看代码的执行


s1 =Student("小张",10)
s1.score= 20

执行结果:
AttributeError: 'Student' object has no attribute 'score'

加上__slots__后该类产生的对象没有__dict__属性:

s1 =Student("小张",10)
print(s1.__dict__)

执行结果:
AttributeError: 'Student' object has no attribute '__dict__'

三、类方法 @classmethod
类方法是操作类的方法,类方法属于类,不属于该类创建的对象
(对象的方法是描述对象的行为的,实际上我们定义的类也是个对象,也有自己的方法)
(对象的方法用来一般用来操作对象的属性(变量),类方法同样一般用来操作类的变量)

说明:
类方法需要使用@classmethod装饰器定义
类方法的第一个参数用来绑定类,约定写为cls
类和对象实例都可以调用类方法
类方法不能访问此类创建的对象的属性

示例:

class A:
    v = 0
    @classmethod
    def get_v(cls):    #调用时传入的是一个类cls,而不是类的对象
        return cls.v

    @classmethod
    def set_v(cls,val):   #等价于A.v = val
        cls.v = val


print(A.get_v())  #此时cls绑定的是A
a = A()
a.set_v(100)
# 类方法实例也可以调,此时cls绑定的是a.__class__
print(a.get_v())

执行结果:
0
100

四、静态方法 @staticmethod
静态方法是定义在类的内部函数,此函数的作用域是类的内部
说明:
静态方法需要使用@static装饰器定义
静态方法和普通函数定义的相同,不需要传入cls或者self
静态方法只能凭借该类变量和实例变量
静态方法不能访问类变量和实例变量

示例:

class A:
    @staticmethod
    def myadd(a,b):
        return a+b
#静态方法不传入cls或者self,自然就找不到对象或者类的属性
#这也是静态方法不能访问类或者对象属性的原因
print(A.myadd(100,200))

a = A()
print(a.myadd(7,9))
#由于该函数是定义在类内的,所以调用必须依赖类或者对象
#否则没法调用
#其实这也是面向对象的思想,将这种看似与类无关的函数封装在类内
#myadd(100,200)    无法调用,解释执行器会找不到这个函数


执行结果:
300
16

猜你喜欢

转载自blog.csdn.net/KingOfMyHeart/article/details/89136822
今日推荐