类的两个装饰器classmethod、staticethod和内置魔术方法
一、两个装饰器@classmethod、@staticmethod
@classmethod:把类中的绑定方法变成一个类方法,cls 就等于类名
有什么用?
1、在方法中任然可以引用类中的静态变量
2、可以不用实例化对象,就直接用类名在外部调用这个方法
什么时候用?
1、定义了一个方法,默认传 self ,但这个 self 没有被使用。
2、并且你在这个方法里用到了当前类名,或者你准备使用这个类的内存空间中的名字的时候
# 商品打折:
class Goods:
__discount = 0.8
def __init__(self, original_price):
self.original_price = original_price
self.price = self.original_price * self.__discount
@classmethod # 把一个对象的绑定方法改成一个类方法
def change_discount(cls, count):
cls.__discount = count # 相当于Goods.__discount = count
Goods.change_discount(0.6) # 类方法可以通过类名调用
# 实例化一个华为手机对象
huawei = Goods(20)
print(int(huawei.price))
huawei.change_discount(0.4) # 类方法可以通过对象调用
# 实例化一个苹果手机对象
apple = Goods(20)
print(int(apple.price))
# 输出
12
8
扩展:
在掉用类的函数的时候就实例化了一个对象
import time
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def today(cls):
structure = time.localtime()
# 在方法中创建一个对象
obj = cls(structure.tm_year, structure.tm_mon, structure.tm_mday)
return obj
# 当调用类中的today方法就会返回一个对象(对象属性不用自己填,today方法已经填好了)
data对象 = Date.today()
print(data对象.year)
print(data对象.month)
print(data对象.day)
# 输出
2021
5
4
@staticmethod:被装饰的方法会成为一个静态方法
本身是一个普通函数,被挪到类的内部执行,那么直接给这个函数添加 @staticmethod 装饰器就可以了
在函数的内部即用不到 self 变量,也用不到 cls 类
class User:
pass
@staticmethod
def login(user):
print(f'{user},登录成功')
User.login('Alen') # 类可以调佣
Bob = User()
Bob.login('Bob') # 对象可以调佣
# 输出
Alen,登录成功
Bob,登录成功
总结:能定义到类中的内容。
1、静态变量:是个所有的对象共享的变量 ——由对象、类调用
2、实例变量:是对象的属性变量 ——由对象调用
3、绑定方法:是个自带self参数的函数 ——由对象调用
4、类方法:是个自带cls参数的函数 ——由对象、类调用
5、property属性:是个伪装属性的方法 ——由对象调用,但不加括号
二、内置魔术方法
__call__方法:对象 + ( ) 调用这个类中的__call__方法
class User:
pass
@staticmethod
def login(user):
print(f'{user},登录成功')
User.login('Alen') # 类可以调佣
Bob = User()
Bob.login('Bob') # 对象可以调佣
# 输出
Alen,登录成功
Bob,登录成功
__len__方法:len (对象) 需要实现这个类中的__len__方法
class A:
def __init__(self):
self.lis = [1, 2, 3, 4, 5]
def len(self):
return len(self.lis)
def __len__(self):
return len(self.lis)
a = A()
print(len(a)) # 可以直接len(a)就可以查看lis里面值的个数
print(a.len()) # 不然就要使用类中的len方法才可以查看
# 输出
5
5
# -------------------------------------------------------------------------------------
# 扩展:也可以使用自定义的函数
class A:
def __init__(self, count):
self.count = count
def __square__(self):
value = self.count ** 2
return value
def square(count):
return A.__square__(count)
a = A(5)
print(square(a))
# 输出
25
__new__方法:实例化的时候会先执行__new__方法用来创建一个对象需要的空间
class A:
def __new__(cls, *args, **kwargs):
o = super().__new__(cls)
print(o) # 内存地址和 self 的内存地址一样
print('执行了__new__方法')
return o
def __init__(self):
print(self)
print('执行了__init__方法')
A() # 实例化对象
# 输出
<__main__.A object at 0x014E0970>
执行了__new__方法
<__main__.A object at 0x014E0970>
执行了__init__方法
__new__方法的设计模式:————>单例模式
一个类,从头到尾,只会创建一次 self 的空间
例如:我有一辆车(有且只有一辆),小红要拿去用,我就给她了,她拿去随便怎么改装,换个红色车漆,换蓝色车轮都可以。但是小明又过来找我要用车,那我就去把我的车给拿回来在给小明,也随小明随便改装。
class Car:
__attribute = None
def __new__(cls, *args, **kwargs):
if cls.__attribute is None: # 当第一次开空间的时候__attribute肯定是空的
# 所以就会开一个新的空间。并把__attribute给赋值,那么以后的都不是第一次了。
cls.__attribute = super().__new__(cls)
return cls.__attribute # 把新空间返回给self
def __init__(self, car_paint, cartwheel_colour):
self.car_paint = car_paint
self.cartwheel_colour = cartwheel_colour
xiao_hong = Car('红色的车漆', '蓝色的车轮')
print('小红的内存地址:', xiao_hong) # 他们的内存地址都是一样的
print(xiao_hong.car_paint) # 红色的车漆————>小红刚拿到的时候还是红色的
xiao_ming = Car('白色的车漆', '黑色的车轮')
print('小名的内存地址:', xiao_ming)
print(xiao_hong.car_paint) # 白色的车漆————>小明在拿过来,把颜色给改成白的了
print(xiao_ming.car_paint) # 白色的车漆————>小红的也变了,应为他们都是同一个车
# 输出
小红的内存地址: <__main__.Car object at 0x01A70A60>
红色的车漆
小名的内存地址: <__main__.Car object at 0x01A70A60>
白色的车漆
白色的车漆
__str__和__repr__方法:
str方法:帮助我们在打印或展示对象的时候更加直观的显示对象内容
1、在打印一个对象的时候,调用__str__方法
2、在 %s 拼接一个对象的时候,调用__str__方法
3、在str一个对象的时候,调用__str__方法
当打印一个对象的时候,希望这个对象显示的值是什么,那么你就必须在这个对象内部实现一个__str__ ,这样的话你就能做到,你在打印这个对象的时候你就能查看到他的内容是多少(查看的内容由你自己在 str 中定义),不然就只能答应一堆内存地址。
repr方法:是 str 的备胎(有str的时候打印str,没有就打印rper),同时 %r 和 repr 有合作关系
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name
def __repr__(self):
return self.age
Bob = User('鲍勃', '18')
print(Bob) # 现在就可以直接打印对象了,——不设置str方法,打印的就是是一堆内存地址,优先打印 str 方法
print('我的名字是%s' % Bob) # 在 %s 拼接一个对象的时候,调用__str__方法
print('我的年龄是%r' % Bob) # 在 %r 拼接一个对象的时候,调用__repr__方法
# 输出
鲍勃
我的名字是鲍勃
我的年龄是18
类的两个装饰器classmethod、staticethod和内置魔术方法的更多相关文章
- Python笔记_第四篇_高阶编程_再议装饰器和再议内置函数
1. 概述: 我们在前面用了很多的装饰器这个工具的方法.这个位置要系统的讲一下装饰器. 1.2 为什么需要装饰器. 装饰器本质是一个Python函数,它可以让其他函数在不需要任何代码变动的前提下增加额 ...
- Python装饰器、生成器、内置函数、json
这周学习了装饰器和生成器,写下博客,记录一下装饰器和生成器相关的内容. 一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如 ...
- python学习笔记(五):装饰器、生成器、内置函数、json
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里 ...
- python基础编程: 函数示例、装饰器、模块、内置函数
目录: 函数示例 装饰器 模块 内置函数 一.函数示例: 1.为什么使用函数之模块化程序设计: 不使用模块程序设计的缺点: 1.体系结构不清晰,可主读性差: 2.可扩展性差: 3.程序冗长: 2.定义 ...
- s14 第4天 关于python3.0编码 函数式编程 装饰器 列表生成式 生成器 内置方法
python3 编码默认为unicode,unicode和utf-8都是默认支持中文的. 如果要python3的编码改为utf-8,则或者在一开始就声明全局使用utf-8 #_*_coding:utf ...
- python第四周:装饰器、迭代器、内置方法、数据序列化
1.装饰器 定义:本质是一个函数,(装饰其他函数)就是为其他函数添加附加功能 原则:不能修改被装饰函数的源代码,不能修改被装饰函数的调用方式 实现装饰器的知识储备: 函数即“变量”.每当定义一个函数时 ...
- 递归,装饰器,python常用内置方法
**递归** def calc(n): print(n) if int(n / 2) == 0: 条件判断 r ...
- python学习笔记之装饰器、生成器、内置函数、json(五)
一.装饰器 装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面 ...
- python之装饰器、生成器、内置函数、JSON
一.装饰器: 装饰器,器在这里的意思是函数,也就是装饰函数.作用是给其他函数添加新功能,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了, ...
随机推荐
- BZOJ_2115 [Wc2011] Xor 【图上线性基】
一.题目 [Wc2011] Xor 二.分析 比较有意思的一题,这里也学到一个结论:$1$到$N$的任意一条路径异或和,可以是一个任意一条$1$到$N$的异或和与图中一些环的异或和组合得到.因为一个数 ...
- jqgrid 实现表格随select框内容改变而刷新
要实现的功能如下:当选择框选择数据源由原始数据切换到组合后数据时,界面左侧jqgrid表格随之改变.效果如下: 实现代码: 界面顶部select选择框:要点是用localStory将选择框的选择信息记 ...
- Python中并发、多线程等
1.基本概念 并发和并行的区别: 1)并行,parallel 同时做某些事,可以互不干扰的同一时刻做几件事.(解决并发的一种方法) 高速公路多个车道,车辆都在跑.同一时刻. 2)并发 concurre ...
- 有必要了解的大数据知识(一) Hadoop
前言 之前工作中,有接触到大数据的需求,虽然当时我们体系有专门的大数据部门,但是由于当时我们中台重构,整个体系的开发量巨大,共用一个大数据部门,人手已经忙不过来,没法办,为了赶时间,我自己负责的系统的 ...
- APP | edxposed框架+trustmealredy模块抓包小程序
出品|MS08067实验室(www.ms08067.com) 本文作者:ketchup(Ms08067实验室 SRSP TEAM小组成员) 一.下载edxposed框架,由于安卓5.0版本以下的不支持 ...
- 阳明-K8S训练营全部文档-2020年08月11日14:59:02更新
阳明-K8S训练营全部文档 Docker 基础 简介 安装 基本操作 Dockerfile Dockerfile最佳实践 Kubernetes 基础 简介 安装 资源清单 Pod 原理 Pod 生命周 ...
- K8S 本地 配置 Local PV 实践
上面我们创建了后端是 hostPath 类型的 PV 资源对象,我们也提到了,使用 hostPath 有一个局限性就是,我们的 Pod 不能随便漂移,需要固定到一个节点上,因为一旦漂移到其他节点上去了 ...
- [SpringCloud教程]3. Eureka服务注册中心集成
新微服务项目多半采用Nacos作为服务注册与发现中心,但是旧项目可能使用Eureka.zookeeper.Consul.Nacos作为服务注册中心. 新项目建议使用Nacos作为服务注册中心 Spri ...
- Java(133-151)【String类、static、Arrays类、Math类】
1.字符串概述和特点 string在lang包里面,因此可以直接使用 字符串的内容不可变 2.字符串的构造方法和直接创建 三种构造方法 package cn.itcast.day08.demo01; ...
- 使用gradle插件发布项目到nexus中央仓库
目录 简介 Gradle Nexus Publish Plugin历史 插件的使用 Groovy DSL Kotlin DSL 插件背后的故事 总结 简介 Sonatype 提供了一个叫做开源软件资源 ...