python类方法、静态方法、属性方法

类方法、静态方法、属性方法

1.概念

  • @classmethod, @staticmethod和@property这三个装饰器的使用对象是在类中定义的函数。
  • @staticmethod装饰器可把其装饰的方法变为一个静态方法;
    不能访问实例变量和类变量的;
    可以通过类名来调用这个方法。
  • @classmethod装饰器可把其装饰的方法变为一个类方法;
    类方法只能访问类变量(全局属性/静态字段),不能访问实例变量。
  • @propertyd装饰器可把其装饰的方法变成一个属性方法(静态属性);
    在属性方法里传参,具体用法 @属性方法名.setter 
    删除属性方法,具体用法 @属性方法名.deleter

https://www.cnblogs.com/wangyongsong/p/6750454.html
https://www.cnblogs.com/revo/p/7381101.html

2.@staticmethod和@classmethod区别?

@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢?
从它们的使用上来看:
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

示例

  • 静态方法@staticmethod:
    静态方法,通过类直接调用,不需要创建对象,不会隐式传递self,没有必须用staticmethod的情况,可以理解未定义在类里的普通函数。
    是一种普通函数,位于类定义的命名空间中,不会对任何实例类型进行操作。
    类方法@classmethod:
  • 类方法,方法中的self是类本身,调用方法时传的值也必须是类的公有属性,就是说类方法只能操作类本身的公有字段。
    常用于定义备选构造方法
class Dog(object):
    food = "gutou"
    age = "1"
    def __init__(self, name):
        self.NAME = name
    @classmethod
    def eat(self, age): #只能是类中的变量
        # print(self.NAME)
        print(age)
        print(self.food)

    @classmethod
    def eat1(self, age):  # 只能是类中的变量
        # print(self.NAME)
        age = "2"
        self.food = "tang"
    @staticmethod
    def print_1():
        print(Dog.food, Dog.age)

d = Dog("labuladuo")
d.eat(Dog.age)    #通过对象调用
Dog.eat(Dog.age)  #通过类调用
print("-----1-----")
d.eat1(Dog.age)
Dog.print_1()
print("--------2-------")
Dog.eat1(Dog.age)
Dog.print_1()
  • 属性方法@property:
    属性变为私有属性,加断言判断属性对错;
    将一个类的函数定义成@property以后, 对象再去使用的时候(obj.name),根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。
    在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现
    把一个方法变成静态属性有什么好处?想要静态变量,为什么不直接定义成一个静态变量?
    如果某个属性的值是一系列动作后才得到的结果(比如一些计算或者条件判断),所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以.
    不能赋值,但是可以通过@proerty.setter装饰器再装饰一下,此时你需要写一个新方法, 对这个flight_status进行更改。@name.deleter修饰可以用于删除操作(del ***)
#1.
class Circle:
    def __init__(self,radius): # 圆的半径radius
        self.radius=radius

    @property
    def area(self):
        return math.pi * self.radius**2 # 计算面积

    @property
    def perimeter(self):
        return 2*math.pi*self.radius # 计算周长

c=Circle(10)
print(c.radius)
print(c.area) # 可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c.perimeter) # 同上
'''
输出结果:
314.1592653589793
62.83185307179586
'''
#2.
class Foo:
    def __init__(self,val):
        self.__NAME=val # 将所有的数据属性都隐藏起来

    @property
    def name(self):
        return self.__NAME # obj.name访问的是self.__NAME(这也是真实值的存放位置)

    @name.setter
    def name(self,value):
        if not isinstance(value,str):  #在设定值之前进行类型检查
            raise TypeError('%s must be str' %value)
        self.__NAME=value  # 通过类型检查后,将值value存放到真实的位置self.__NAME

    @name.deleter
    def name(self):
        raise TypeError('Can not delete')

f = Foo('egon')
print(f.name)
f.name = '10' # 可以赋值
print(f.name) # 输出 10
f.name = 10 # 抛出异常'TypeError: 10 must be str'
del f.name # 抛出异常'TypeError: Can not delete'

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值