python之静态属性,类方法,静态方法

一、静态属性

静态属性:是将类中的函数封装,实现像调用数据属性一样的方式调用函数属性,在python中利用@property语句实现

封装的概念:使得调用者无法察觉到被调用对象的实现逻辑,就是对象的封装

1、不利用@property的方式
class Room:
    def __init__(self, name, owner, width, length, height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height

    def cal_area(self):
        print("%s住的%s,面积为%s" % (self.owner, self.name, self.width * self.length))

R1 = Room("公寓", "MB", 100, 100, 100)
R1.cal_area()	# 这里可以被看出调用的是一个函数属性

结果:

MB住的公寓,面积为10000
2、利用@property的方式
class Room:
    def __init__(self, name, owner, width, length, height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height

    @property
    def cal_area(self):
        return self.width * self.length	   # 注意为了实现和数据属性相同的调用方式,需要加入return值

R1 = Room("公寓", "MB", 100, 100, 100)
print(R1.name)
print(R1.cal_area)    # 这里函数属性的调用已经完全和数据属性相同了

结果:

公寓
10000
3、property的延伸

一个静态属性property本质就是实现了get,set,delete三种方法

(1)方法一:

class Foo:
    @property
    def AAA(self):
        print('get的时候运行我啊')

    @AAA.setter
    def AAA(self,value):
        print('set的时候运行我啊')

    @AAA.deleter
    def AAA(self):
        print('delete的时候运行我啊')

# 只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1=Foo()
f1.AAA      # get的时候运行我啊
f1.AAA='aaa'    # set的时候运行我啊
del f1.AAA      # delete的时候运行我啊

(2)方法二:

class Foo:
    def get_AAA(self):
        print('get的时候运行我啊')

    def set_AAA(self,value):
        print('set的时候运行我啊')

    def delete_AAA(self):
        print('delete的时候运行我啊')
    AAA=property(get_AAA,set_AAA,delete_AAA) # 内置property三个参数与get,set,delete一一对应

f1=Foo()
f1.AAA      # get的时候运行我啊
f1.AAA='aaa'    # set的时候运行我啊
del f1.AAA      # delete的时候运行我啊

(3)案例1:

class Goods:

    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8

    @property
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price

obj = Goods()
obj.price         # 获取商品价格
print("111---->",obj.price)
print("222---->",obj.__dict__)
obj.price = 200   # 修改商品原价
print("333---->",obj.__dict__)
print("444---->",obj.price)
del obj.price     # 删除商品原价
print("555---->",obj.__dict__)

结果:

111----> 80.0
222----> {'original_price': 100, 'discount': 0.8}
333----> {'original_price': 200, 'discount': 0.8}
444----> 160.0
555----> {'discount': 0.8}

(4)案例2:实现类型检测功能

第一关:

p1=People(‘alex’) # property自动实现了set和get方法属于数据描述符,比实例属性优先级高,所以你这面写会触发property内置的set,抛出异常

class People:
    def __init__(self,name):
        self.name=name

    @property
    def name(self):
        return self.name
p1=People('alex')    # 会报错

第二关:修订版

class People:
    def __init__(self,name):
        self.name=name   # 实例化就触发property

    @property
    def name(self):
        # return self.name    # 无限递归
        print('get------>')
        return self.DouNiWan

    @name.setter
    def name(self,value):
        print('set------>')
        self.DouNiWan=value

    @name.deleter
    def name(self):
        print('delete------>')
        del self.DouNiWan

p1=People('alex')   # self.name实际是存放到self.DouNiWan里
print("111-->",p1.name)
print("222-->",p1.name)
print("333-->",p1.name)
print("444-->",p1.__dict__)

p1.name='egon'
print("555-->",p1.__dict__)

del p1.name
print("666-->",p1.__dict__)

结果:

111--> alex
get------>
222--> alex
get------>
333--> alex
444--> {'DouNiWan': 'alex'}
set------>
555--> {'DouNiWan': 'egon'}
delete------>
666--> {}

第三关:加上类型检查

class People:
    def __init__(self,name):
        self.name=name   # 实例化就触发property

    @property
    def name(self):
        # return self.name #无限递归
        print('get------>')
        return self.DouNiWan

    @name.setter
    def name(self,value):
        print('set------>')
        if not isinstance(value,str):
            raise TypeError('必须是字符串类型')
        self.DouNiWan=value

    @name.deleter
    def name(self):
        print('delete------>')
        del self.DouNiWan

p1=People('alex')   # self.name实际是存放到self.DouNiWan里   # set------>
p1.name=1    # 会报错

二、类方法

类方法:是用在需要类中的函数不和实例捆绑时,即不通过实例去调用类的某个函数(函数末尾有self参数,就说明了这个函数和实例绑定。有cls参数,就说明和类绑定)

利用@classmethod语句,将某个属性只和类绑定而不和实例绑定

1、不利用@classmethod的方法
class Room:
    tag = 1

    def __init__(self, name, owner, width, length, height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height
        
R1 = Room("公寓", "MB", 100, 100, 100)
print(R1.tag)    # 想得出这个tag,需要产生一个实例并调用它的tag属性

结果:

1
2、利用@classmethod的方法
class Room:
    tag = 1

    def __init__(self, name, owner, width, length, height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height

    @classmethod
    def tell_info(cls):
        print(cls.tag)

R1 = Room("公寓", "MB", 100, 100, 100)
Room.tell_info()   # python会自动将Room传给cls参数

结果:

1

通过@classmethod定义过的方法就是给类用的,R1.tell_info()虽然也可以运行,但是不规范(相当于R1将自己所属的类传入了cls)

三、静态方法

静态方法:只是名义上归属类管理,通过类和实例都可以调用,即这个属性既不和实例绑定也不和类绑定,叫做类的工具包

通过@staticmethod语句,实现类的静态方法

class Room:

    def __init__(self, name, owner, width, length, height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height

    @staticmethod
    def take_shower(name1, name2, name3):
        print("%s,%s,%s is taking shower together" % (name1, name2, name3))

R1 = Room("公寓", "MB", 100, 100, 100)

Room.take_shower("CJJ", "MB", "LGJ")	# 通过类可以调用
R1.take_shower("CJJ", "MB", "LGJ")	# 通过实例可以调用

结果:

CJJ,MB,LGJ is taking shower together
CJJ,MB,LGJ is taking shower together

如果不写@staticmethod,例如def test():
这个函数只能通过类调用,不能实例调用

四、总结

静态属性:即可以访问实例属性,也可以访问类属性
类方法:可以访问类属性,不能访问实例属性
静态方法:不能访问类属性也不能访问实例属性

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值