两个装饰器
classmethod : 被装饰的方法会成为一个静态方法
classmethod 什么时候用?
- 定义了一个方法,默认传self,但是这个self没有被用到
- 并且你在这个方法里用到了当前的类名,或者你准备使用这个类的内存空间中的名字的时候
定义:
装饰器怎么加
参数怎么改
class Goodds: __dicount = 0.8 def __init__(self): self.__Price = 5 self.price = self.__Price * self.__dicount @classmethod def change_discount(cls, new_discount): cls.__dicount = new_discount
用法:
调用方法
class Goodds: __dicount = 0.8 def __init__(self): self.__Price = 5 self.price = self.__Price * self.__dicount @classmethod def change_discount(cls, new_discount): cls.__dicount = new_discount# 类方法可以通过类名调用Goodds.change_discount(0.6)apple = Goodds()print(apple.price)# 类方法可以通过对象名调用apple.change_discount(0.5)apple2 = Goodds()print(apple2.price)# import time# class Date:# def __init__(self, year, month, day):# self.year = year# self.month = month# self.day = day# # @classmethod# def today(cls):# struct_t = time.localtime()# date = cls(struct_t.tm_year, struct_t.tm_mon, struct_t.tm_mday)# return date# # # date_obj = Date.today()# print(date_obj.year)# print(date_obj.month)# print(date_obj.day)# # 2019# # 6# # 5
staticmethod : 被装饰的方法会成为一个静态方法
用在:
帮助我们把一个普通的函数挪到类中来直接使用,制造静态方法用的
定义:
class User:# @staticmethod# def login(a, b):# print("登陆逻辑", a, b)# # 在函数的内部既不会用到self变量,也不会用到cls类# 本身是一个普通的函数,被挪到类的内部执行,那么直接给这个函数添加@staticmethod装饰器就可以了
调用方法:
# class User:# @staticmethod# def login(a, b):# print("登陆逻辑", a, b)# # 在函数的内部既不会用到self变量,也不会用到cls类## obj = User()# User.login(1, 2)# obj.login(3, 4)
class A: country = '中国' def func(self): print(self.__dict__) @classmethod def clas_func(cls): print(cls) @staticmethod def stat_func(): print("普通函数") @property def name(self): return 'wahah'# 能定义到类中的内容# 静态变量 是个所有的对象共享的变量 有对象\类调用 但是不能重新赋值# 绑定方法 是个自带self参数的函数 由对象调用# 类方法 是个自带cls参数的函数 由对象\类调用# 静态方法 是个啥都不带的普通函数 由对象\类调用# property属性 是个伪装成属性的方法 由对象调用 但不加括号
一些内置的魔术方法
___new___class A: def __new__(cls, *args, **kwargs): o = object.__new__(cls) print("执行new", o) return o def __init__(self): print('执行initt', self)A()# 执行new <__main__.A object at 0x0000002F1E569048># 执行initt <__main__.A object at 0x0000002F1E569048># 实例化的时候,# 先创建一块对象的空间,有个指针能指向类 --》 __new__# 调用init--> __init__# 设计模式 -- 单例模式# 一个类,从头到尾只会创建一次self的空间class Baby: __instance = None def __new__(cls, *args, **kwargs): if cls.__instance is None: # cls.__instance = super().__new__(cls) cls.__instance = object.__new__(cls) return cls.__instance def __init__(self, cloth, pants): self.cloth = cloth self.pants = pantsb1 = Baby('红毛衣', '绿裤子')print(b1.cloth)b2 = Baby('白衬衫', '黑裤子')print(b1.cloth)print(b2.cloth)# 单例模式2.0:class Baby: def __init__(self, cloth, pants): self.cloth = cloth self.pants = pantsb1 = Baby('红上衣', '绿裤子')# 通过模块引用的方式# from 单例模式 import b1# from 单例模式 import b1
__cal__""" Call self as a function. """# class A:# pass## obj = A()# print(callable(obj))# Falseclass A: def __call__(self, *args, **kwargs): print('___', args)obj = A()print(callable(obj))obj()# True# ___ ()
__len__class Cls: def __init__(self, name): self.name = name self.student = [] def len(self): return len(self.student) def __len__(self): return len(self.student)py22 = Cls('py22')py22.student.append('abc')py22.student.append('123')py22.student.append('qaz')print(len(py22))class Pow: def __init__(self, n): self.n = n def __pow2__(self): return self.n ** 2def pow2(obj): return obj.__pow2__()obj = Pow(10)print(pow2(obj))
__str__class Course:# def __init__(self, name, price, period):# self.name = name# self.price = price# self.period = period# # def __str__(self):# return self.name# # python = Course('python', 21800, '6 month')# linux = Course('linux', 19800, '5 month')# mysql = Course('mysql', 12800, '3 month')# go = Course('go', 15800, '4 month')# print(go)# # goclass cls: def __init__(self): self.student = [] def append(self, name): self.student.append(name) def __str__(self): return str(self.student)py22= cls()py22.append('大壮')print("我们py22班 %s" %py22)print(py22)py22.append('小状')print(py22)# 在打印一个对象的时候 调用__str__方法# 在%s拼接一个对象的时候 调用__str__方法# 在str一个对象的时候 调用__str__方法
__repr__py22 = clas()py22.append('大壮')print(py22)print(str(py22))print('我们py22班 %s'%py22)print('我们py22班 %r'%py22)print(repr(py22))# 当我们打印一个对象 用%s进行字符串拼接 或者str(对象)总是调用这个对象的__str__方法# 如果找不到__str__,就调用__repr__方法# __repr__不仅是__str__的替代品,还有自己的功能# 用%r进行字符串拼接 或者用repr(对象)的时候总是调用这个对象的__repr__方法