看原码:
class Goods: discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return self.__price*self.discount def set_price(self,new_price): if new_price and type(new_price) is int: #这里保护了输入的数据为合法数据 self.__price=new_price else: print('请输入正确的价格数据') apple=Goods('苹果',5) print(apple.discount)
首先我们有一个需求;商品的折扣是人为定的,与商品中的对象无关。即Goods中的折扣直接通过Goods去更改,而不是要先创建一个Goods对象再去改。因为这个折扣将对所有的商品生效的。
上面的代码显示:要先有了apple的基础上才能去更改discount。如果再创建一个”banana“商品,其折扣仍旧是0.5,显示这不是我们想要的效果。
故我们使用类方法@classmethod来解决这个问题。见代码:
class Goods: __discount=0.5 def __init__(self,name,price): self.name=name self.__price=price @property def price(self): return self.__price*self.__discount def set_price(self,new_price): if new_price and type(new_price) is int: #这里保护了输入的数据为合法数据 self.__price=new_price else: print('请输入正确的价格数据') @classmethod def set_discount(cls,new_discount): #将self替代为cls,用于这个类 cls.__discount=new_discount return self.__discount apple=Goods('苹果',6) Goods.set_discount(0.8) print(apple.price)
即把一个方法变成一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象。
当这个方法的操作只涉及静态属性的时候,就应该使用这个classmethod来装饰这个方法。
再讲到静态方法的作用。
类中的方法,有一些不需要传self,这个时候就要用到staticmethod来装饰这个方法。同时当该类的属性需要类中的方法进行初始时,也可以通过静态方法装饰器来解决这个问题。
例如:有一个登陆类,其属性要有name,password。但这个name 和password怎么来的呢。我们不允许类外去创建时,就可以用到静态方法。
见代码:
class Login(): def __init__(self,name,pwd): self.name=name self.pwd=pwd def login(self):pass def get_usr_pwd(self): name=input('用户名>>') pwd=input('密码>>>') Login(name,pwd)
Login.get_usr_pwd()
在完全面向对象的程序中,如果一个函数即与类无关,也与对象无关,那么就用staticmethod。
静态方法和类方法都是类调用的。
对象可以调用类方法和静态方法吗?
答案是可以的。一般情况下,推荐用类名调用。
类方法有一个默认参数cls代表这个类。可以用别的名词来替代,但不建议用别的名词。
静态方法没有默认参数,就像普通函数一样。是可以传参的。