python中类class的魔法方法

news2025/1/21 5:55:05

开始介绍之前,我们先看下之前文章我们介绍过的内置类merryview的一些方法,如下图所示: 有很多双下划线开始和结束的method,这么多method是做啥子用的呢?

其实这些方法就是我们常说的魔法方法,也是python中的特殊方法。它们以双下划线 __ 开始和结束,这些方法为 Python 类提供了丰富的功能。

以下开始介绍下常见的魔法方法:

1 构造方法

构造方法有__new__ __init__ __del__

__new__:如果设置了该方法,当我们定义类的实例时,该方法会被第一个调用,而不是先调用__init__方法。该方法需要返回一个类的实例。

__init__: 初始化类的实例属性,并可在该方法中定义其他一些属性或者调用其他函数等作为初始化的功能。

__del__: 当类实例对象销毁时会自动调用该方法。

举例:定义一个类,并做类的实例化

class Car(object):
  def __init__(self,brand,color,cost_performance):
    print('__init__被调用')
    self.brand = brand
    self.color = color
    self.cost_performance = cost_performance

  def __new__(cls, *args, **kwargs):
  	print('__new__被调用')

  def __del__(self):
  	print('__del__被调用')

实例化类:

car_ins = Car('BYD','black','high')
print(car_ins.brand)

当执行时,发现报错如下:只有__new__方法被调用了,而没有调用__init__,所以在打印实例属性时报错。

原因是__new__方法中没有返回对象实例。

我们在__new__方法中添加如下一行代码:super().__new__(cls)

def __new__(cls, *args, **kwargs):
  print('__new__被调用')
  return super().__new__(cls)

再次实例化类的时候

car_ins = Car('BYD','black','high')
print(car_ins.brand)

打印结果如下:

__new__被调用
__init__被调用
BYD
__del__被调用

解释:增加的这一行super().__new__(cls)作用就是调用基类object创建一个实例并返回,有了实例然后再调用__init__ 方法做初始化。当程序执行完成后,实例对象的内存会被释放,然后自动调用__del__方法。

2 类的表示方法

类的表示方法主要有__repr__ __str__

  1. __str__:当使用print函数打印对象实例或者str函数转换对象实例时,会调用该方法返回的字符串,如果没有该方法会继续找__repr__方法中的字符串信息
  2. __repr__:当使用repr函数打印对象实例时,会调用该方法返回的字符串,如果没有该方法会继续找__str_方法中的字符串信息

举例:

class Car(object):
  def __init__(self,brand,color,cost_performance):
    print('__init__被调用')
    self.brand = brand
    self.color = color
    self.cost_performance = cost_performance
  def __str__(self):
    print('__str__被调用')
    return '我是Car类'
  def __repr__(self):
    print('__repr__被调用')
    return '我是Car类'

类实例化后,打印下类实例:

car_ins = Car('BYD','black','high')
print(car_ins)
print(str(car_ins))
print(repr(car_ins))

结果:

__str__被调用
我是Car类
__str__被调用
我是Car类
__repr__被调用
我是Car类

3 上下文管理器方法

通过定义一个类,并实现__enter__()和__exit__()方法,那么这个类就可以被称为上下文管理器,也就可以使用with as的语句。

__enter__()方法:返回一个值,可以将它赋值给with...as后面的对象。

__exit__()方法: with...as 语句退出或者发送异常时会执行这个方法。

比如之前我们的文章讲到open函数我们经常会用到上下文管理器:

with open('test.txt','r') as fd:
	content = fd.readlines ()

4 可迭代对象和迭代器方法

方法有 __iter__ __next__

  • 可迭代对象:指python中可以用来迭代(支持for循环)的对象,比如常见的列表/元组/字典/字符串等,这些对象中都会定义__iter__魔法方法。
  • 迭代器:指可以帮助我们迭代其他对象的一种对象。这类对象会定义__next__魔法方法,可通过next()函数获取迭代的结果。

可迭代对象不一定是迭代器,但迭代器肯定是可迭代对象。因为迭代器要求必须同时实现__iter__方法和__next__方法, 而一旦实现了__iter__方法就必然是一个可迭代对象。但是反过来则不成立,可迭代对象可以不是迭代器。

1)判断对象是可迭代对象和迭代器

在python模块中先导入Iterable和Iterator。

from typing import Iterable,Iterator
或者
from collections.abc import Iterable,Iterator

通过isinstance(Object, Iterable)可判断一个对象是否是可迭代对象

通过isinstance(Object, Iterator)可判断一个对象是否是迭代器

2)常见的列表等是可迭代对象,但不是迭代器。

#定义一个列表
listA = [1,4,3,2]
print(f'列表是否是迭代对象 :{isinstance(listA,Iterable)}')
print(f'列表是否是迭代器 {isinstance(listA,Iterator)}')
#结果:
列表是否是迭代对象 :True
列表是否是迭代器 False

python安装好后有个自带的模块builtins.py,找到定义的list类,会发现该类中定义了__iter__方法,没有定义__next__方法。

class list(object):
  """
  Built-in mutable sequence.
  If no argument is given, the constructor creates a new empty list.
  The argument must be an iterable if specified.
  """
  def append(self, *args, **kwargs): # real signature unknown
    """ Append object to the end
    .....
  def __iter__(self, *args, **kwargs): # real signature unknown
    """ Implement iter(self). """
    pass

使用next()执行列表会报错列表不是一个迭代器。

next(listA)
#会报错如下
Traceback (most recent call last):
File "test.py", line 9, in <module>
next(listA)
TypeError: 'list' object is not an iterator

3)使用iter()将可迭代对象转换为迭代器

还是以上面的列表举例,使用iter()将列表转换为迭代器。

list_iter = iter(listA)
print(f'列表使用iter()后是否是迭代对象 :{isinstance(list_iter,Iterable)}')
print(f'列表使用iter()是否是迭代器 {isinstance(list_iter,Iterator)}')
#打印结果
列表使用iter()后是否是迭代对象 :True
列表使用iter()是否是迭代器 True

5 容器方法

容器方法主要有__len__ __getitem__ __setitem__ __delitem__ __contains__ __reversed__

  • __len__(self ): 获取容器中元素的数量,配合len() 函数使用。
  • __getitem__(self, index): 获取容器中的元素值,index表示容器中的索引。
  • __setitem__(self, index, value): 设置容器中的元素值,index表示容器中的索引,value表示要设置的值。
  • __delitem__(self, index): 删除容器中的元素,index表示容器中的索引。
  • __contains__(self, item): 判断容器中是否包含某个元素,使用in 判断。
  • __reversed__(self): 当使用reversed() 内建函数会调用该方法,定义为返回一个反转之后的序列。

举例:自定义一个列表对象,并初始化一个传入的列表

class MyList(object):
  def __init__(self,newlist):
  	self.newlist = newlist
  def __len__(self):
  	print('使用了__len__')
  	return len(self.newlist)
  def __getitem__(self,index):
  	print('使用了__getitem__')
  	return self.newlist[index]
  def __setitem__(self, index, value):
  	print('使用了__setitem__')
  	self.newlist[index] = value
  def __delitem__(self, index):
  	print('使用了__delitem__')
  	del self.newlist[index]
  def __contains__(self, item):
  	print('使用了__contains__')
  	return item in self.newlist
  def __reversed__(self):
  	print('使用了__reversed__')
		return reversed(self.newlist)

对自定义列表对象进行增删改查时,会用到上述魔法方法:

先初始化实例:

mylist1 = MyList([1,2,3,4,5])

1)获取元素个数:

print(f'初始元素个数:{len(mylist1)}')

结果:

使用了__len__
初始元素个数:5

2)获取元素值

print(f'index为1的值:{mylist1[1]}')

结果:

使用了__getitem__
index为1的值:2

3)设置元素值

mylist1[0] = 100
print(f'index为0的值:{mylist1[0]}')

结果:

使用了__setitem__
使用了__getitem__
index为0的值:100

4)删除元素的值

del mylist1[-1]
print(f'删除最后一个元素后列表为:{list(mylist1)}')

结果:

使用了__delitem__
使用了__len__
使用了__getitem__
使用了__getitem__
使用了__getitem__
使用了__getitem__
使用了__getitem__
删除最后一个元素后列表为:[100, 2, 3, 4]

5)判断是否包含某个元素

print(f'判断数字2是否在列表内:{2 in mylist1}')

结果:

使用了__contains__
判断数字2是否在列表内:True

6)反转序列

print(list(reversed(mylist1)))

结果:

使用了__reversed__
[4, 3, 2, 100]

6 比较方法

比较方法主要有__eq__ __lt__ __le__ __gt__ __ge__ __ne__

  • __eq__(self, other):定义等于操作符(==)的行为。
  • __ne__(self, other):定义不等于操作符(!=)的行为。
  • __lt__(self, other):定义小于操作符(<)的行为。
  • __gt__(self, other):定义大于操作符(>)的行为。
  • __le__(self, other):定义小于等于操作符(<=)的行为。
  • __ge__(self, other):定义大于等于操作符(>=)的行为。

举例:定义一个类,初始化时随机生成一个整数。

import random
class rnum(object):
  def __init__(self,num):
  	self.num = random.randint(0,num)
  def __eq__(self,other:int):
  	print('使用了__eq__')
  	return self.num == other
  def __le__(self,other:int):
  	print('使用了__getitem__')
  	return self.num <= other
  def __ge__(self, other:int):
  	print('使用了__ge__')
  	return self.num >= other
  def __lt__(self, other:int):
  	print('使用了__lt__')
  	return self.num < other
  def __gt__(self, other:int):
 		print('使用了__gt__')
  	return self.num > other
  def __ne__(self,other:int):
  	print('使用了__ne__')
  	return self.num != other

初始化类,传入数字10,并将对象做比较运算。

newnum = rnum(10)
print(f'newnum.num = {newnum.num}')
#比较对象值的数字7的大小
print(f'判断== : {newnum == 7}')
print(f'判断>= : {newnum >= 7}')
print(f'判断>= : {newnum >= 7}')
print(f'判断< : {newnum < 7}')
print(f'判断> : {newnum > 7}')
print(f'判断!= : {newnum != 7}')

#结果:

newnum.num = 1
使用了__eq__
判断== : False
使用了__ge__
判断>= : False
使用了__ge__
判断>= : False
使用了__lt__
判断< : True
使用了__gt__
判断> : False
使用了__ne__
判断!= : True

7 算术方法

常用到的算术方法如下:

__add__(self, other):实现加法+操作。

__sub__(self, other):实现减法-操作。

__mul__(self, other):实现乘法*操作。

__floordiv__(self, other):实现使用//操作符的整数除法。

__div__(self, other):实现使用/操作符的除法。

__mod__(self, other):实现%取余操作。

__divmod__(self, other):实现 divmod 内建函数。__pow__:实现冥运算**操作

__lshift__(self, other):实现左移位运算符<<。

__rshift__(self, other):实现右移位运算符>>。

__and__(self, other):实现按位与运算符&。

__or__(self, other):实现按位或运算符|。

__xor__(self, other):实现按位异或运算符^。

举例:定义一个类,初始化时随机生成一个整数。

import random
class rnum(object):
  def __init__(self,num):
  	self.num = random.randint(0,num)
  def __add__(self,other:int):
  	print('使用了__add__')
  	return self.num + other
  def __sub__(self,other:int):
  	print('使用了__sub__')
  	return self.num - other
  def __mul__(self, other:int):
  	print('使用了__mul__')
  	return self.num * other
  def __floordiv__(self, other:int):
  	print('使用了__floordiv__')
  	return self.num // other
  def __mod__(self,other:int):
  	print('使用了__mod__')
  	return self.num % other
  def __divmod__(self,other:int):
  	print('使用了__divmod__')
  	return divmod(self.num,other)
  def __pow__(self,other:int):
  	print('使用了__pow__')
  	return self.num ** other
  def __lshift__(self,other:int):
  	print('使用了__lshift__')
  	return self.num << other
  def __rshift__(self,other:int):
  	print('使用了__rshift__')
  	return self.num >> other
  def __and__(self,other:int):
  	print('使用了__and__')
  	return self.num & other
  def __or__(self,other:int):
  	print('使用了__or__')
  	return self.num | other
  def __xor__(self,other:int):
  	print('使用了__xor__')
  	return self.num ^ other

初始化类,并计算如下:

1)按数值计算

newnum = rnum(100)
print(f'newnum.num = {newnum.num}')
print(f'加法: {newnum + 3}')
print(f'减法 : {newnum - 3}')
print(f'乘法 : {newnum * 3}')
print(f'//除法 : {newnum // 3}')
print(f'计算余数 : {newnum % 3}')
print(f'计算商和余数 : {divmod(newnum,3)}')
print(f'计算冥次 : {newnum ** 3}')

#结果

newnum.num = 41
使用了__add__
加法: 44
使用了__sub__
减法 : 38
使用了__mul__
乘法 : 123
使用了__floordiv__
//除法 : 13
使用了__mod__
计算余数 : 2
使用了__divmod__
计算商和余数 : (13, 2)
使用了__pow__
计算冥次 : 68921
2)按位进行计算:指转换为2进制后的一些计算
print(f'计算左移<< : {newnum << 3}')
print(f'计算右移>> : {newnum >> 3}')
print(f'计算位与& : {newnum & 3}')
print(f'计算位或| : {newnum | 3}')
print(f'计算位异或^ : {newnum ^ 3}')

#结果

使用了__lshift__
计算左移<< : 328
使用了__rshift__
计算右移>> : 5
使用了__and__
计算位与& : 1
使用了__or__
计算位或| : 43
使用了__xor__
计算位异或^ : 42

解释按位计算的示例:

print(f'数字41的2进制数:{bin(41)}')
print(f'2进制转为10进制数:{int("0b101001",base=2)}')

#0b101001 整体往左移3位变成0b101001000
print(f'2进制转为10进制数:{int("0b101001000",base=2)}')

#0b101001 整体往右移3位变成0b101
print(f'2进制转为10进制数:{int("0b101",base=2)}')

#0b101001 与数字3(0b11) 做&的运算 得到0b000001
print(f'2进制转为10进制数:{int("0b000001",base=2)}')

#0b101001 与数字3(0b11) 做|的运算 得到0b101011
print(f'2进制转为10进制数:{int("0b101011",base=2)}')

#0b101001 与数字3(0b000011) 做^的运算 得到0b101010
print(f'2进制转为10进制数:{int("0b101010",base=2)}')

结果:跟上面按位运算的结果一致

数字41的2进制数::0b101001
2进制转为10进制数::41
2进制转为10进制数::328
2进制转为10进制数::5
2进制转为10进制数::1
2进制转为10进制数::43
2进制转为10进制数::42

补充知识:

  • 按位左移:将一个数的各二进制位全部左移若干位,右边多出的位将用0填充。
  • 按位右移:将一个数的各二进制位全部右移若干位,左边多出的位将用0填充。
  • 按位与:只有当两个对应位都为1时,结果才为1,否则结果为0
  • 按位或:只要有一个对应位为1时,结果就为1,都为0时结果为0
  • 按位异或:相同为0,不同为1:如果两个比较的位相同,则结果为0;如果不同,则结果为1。

8 属性方法

关于属性相关的有以下方法:

__dir__(self):定义对类的实例调用 dir() 时的行为,返回一个属性列表。

__getattr__(self,name):当用户试图访问一个不存在的属性时,会调用该方法。

__setattr__(self,name,value):自定义某个属性的赋值时调用该方法。

__delattr__(self,name):删除某个属性时调用该方法。

举例:定义一个类以及上面的方法

class Car(object):
  def __init__(self,brand,color,cost_performance):
  	print('__init__被调用')
  	self.brand = brand
  	self.color = color
  	self.cost_performance = cost_performance
  def __dir__(self):
  	print('__dir__被调用')
  	return ['brand','color','cost_performance']
  def __getattr__(self, name):
  	print('__getattr__被调用')
  	return self.__dict__.get(name)
  def __setattr__(self,name,value):
  	print('__setattr__被调用')
  	self.__dict__[name] = value
  def __delattr__(self,name):
  	print('__delattr__被调用')
  	del self.__dict__[name]

类实例化

car_ins = Car('BYD','black','high')

1)返回实例的属性列表

print(dir(car_ins))

结果:

__dir__被调用
['brand', 'color', 'cost_performance']

2)返回实例的属性字典

print(car_ins.__dict__)

结果:

{'brand': 'BYD', 'color': 'black', 'cost_performance': 'high'}

3)获取某个属性

print(car_ins.other)

结果:因为没有该属性,所以返回为None

__getattr__被调用
None

4)设置属性

car_ins.other = 'xxx'
print(car_ins.__dict__)

结果:

__setattr__被调用
{'brand': 'BYD', 'color': 'black', 'cost_performance': 'high', 'other': 'xxx'}

5)删除属性

del car_ins.other
print(car_ins.__dict__)

结果:

__delattr__被调用
{'brand': 'BYD', 'color': 'black', 'cost_performance': 'high'}

共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习和关注,谢谢大家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1978563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【代码随想录】二分查找

文章为代码随想录的学习笔记&#xff0c;链接&#xff1a; 代码随想录 只要看到面试题中给出的数组是有序数组&#xff0c;都可以想一想是否可以使用二分法。 基本概念 二分查找要求线性表必须采用顺序存储结构&#xff0c;而且表中元素按关键字有序排列。‘ 查找过程&…

2024年华数杯数学建模竞赛——赛题浅析

本次华数杯与国赛同频【第一天下午六点发题&#xff0c;第四天下午八点收卷】&#xff0c;一共74小时。难度约为国赛的0.8&#xff0c;题量约为国赛的0.8-0.9.非常适合作为国赛前的练手赛。下面为大家带来本次华数杯的选题建议&#xff0c;希望对大家有所帮助。 一图流 选题人…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 卢小姐的字符串解压缩(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM金牌🏅️团队| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题…

36-38 关系数据库入门

关系数据库入门 关系数据库概述 数据持久化 - 将数据保存到能够长久保存数据的存储介质中&#xff0c;在掉电的情况下数据也不会丢失。 数据库发展史 - 网状数据库、层次数据库、关系数据库、NoSQL数据库。 1970年&#xff0c;IBM的研究员E.F.Codd在Communication of the ACM…

【Material-UI】Autocomplete中的禁用选项:Disabled options

文章目录 一、简介二、基本用法三、进阶用法1. 动态禁用2. 提示禁用原因3. 复杂的禁用条件 四、最佳实践1. 一致性2. 提供反馈3. 优化性能 五、总结 Material-UI的Autocomplete组件提供了丰富的功能&#xff0c;包括禁用特定选项的能力。这一特性对于限制用户选择、提供更好的用…

长短期记忆网络LSTM

目录 一、LSTM提出的背景&#xff1a;1.RNN存在的问题&#xff1a;2.LSTM的思想&#xff1a;2.1回顾GRU的提出&#xff1a;2.2LSTM在GRU上的改进&#xff1a; 二、遗忘门、输入门、输出门&#xff1a;三、LSTM网络架构&#xff1a;1.候选记忆单元C~t&#xff1a;2.遗忘门、输入…

顶刊TPAMI 2024!无需全标注,仅用少量涂鸦标注即可获得确定和一致的语义分割预测结果...

本文介绍了山东大学&#xff0c;北京大学和纽约州立大学石溪分校合作开展的一项工作。该工作面向图像涂鸦弱标注语义分割任务&#xff0c;重点关注采用涂鸦弱标注时语义分割网络的不确定性和不一致性问题。 作者提出最小化熵损失函数和网络嵌入的随机游走过程来分别改善分割网络…

Altera之FPGA器件系列简介

目录 一、前言 二、命名规则 2.1 MAX V系列 2.2 Cyclone 系列 2.3 Arria 系列 2.4 Stratix 系列 2.5 Agilex 系列 三、器件划分 3.1 工艺制程 3.2 使用领域 四、参考 一、前言 Altera是作为FPGA领域的头部企业&#xff0c;是一家老牌的技术公司&#xff0c;成立于19…

【一图学技术】7.削峰与限流防刷技术解决方案及限流算法图解

削峰与限流防刷技术 一、削峰技术 ✈解决问题&#xff1a;解决流量大的问题&#xff0c;限制单机流量 &#x1f680;核心技术&#xff1a; 秒杀令牌&#xff1a;颁发给用户令牌&#xff0c;给予操作特权 秒杀大闸&#xff1a;限制令牌数量 队列泄洪&#xff1a;队列增加缓…

4_损失函数和优化器

教学视频&#xff1a;损失函数与反向传播_哔哩哔哩_bilibili 损失函数&#xff08;Loss Function&#xff09; 损失函数是衡量模型预测输出与实际目标之间差距的函数。在监督学习任务中&#xff0c;我们通常希望模型的预测尽可能接近真实的目标值。损失函数就是用来量化模型预…

神经网络基础--激活函数

&#x1f579;️学习目标 &#x1f579;️什么是神经网络 1.神经网络概念 2.人工神经网络 &#x1f579;️网络非线性的因素 &#x1f579;️常见的激活函数 1.sigmoid激活函数 2.tanh激活函数 3.ReLU激活函数 4.softmax激活函数 &#x1f579;️总结 &#x1f57…

计算机基础(Windows 10+Office 2016)教程 —— 第5章 文档编辑软件Word 2016(上)

第5章 文档编辑软件Word 2016 5.1 Word 2016入门5.1.1 Word 2016 简介5.1.2 Word 2016 的启动5.1.3 Word 2016 的窗口组成5.1.4 Word 2016 的视图方式5.1.5 Word 2016 的文档操作5.1.6 Word 2016 的退出 5.2 Word 2016的文本编辑5.2.1 输入文本5.2.3 插入与删除文本5.2.4 复制与…

二进制与进制转换与原码、反码、补码详解--内含许多超详细图片讲解!!!

前言 今天给大家分享一下C语言操作符的详解&#xff0c;但在此之前先铺垫一下二进制和进制转换与原码、反码、补码的知识点&#xff0c;都非常详细&#xff0c;也希望这篇文章能对大家有所帮助&#xff0c;大家多多支持呀&#xff01; 操作符的内容我放在我的下一篇文章啦&am…

基于人工智能的口试模拟、LLM将彻底改变 STEM 教育

概述 STEM教育是一种整合科学&#xff08;Science&#xff09;、技术&#xff08;Technology&#xff09;、工程&#xff08;Engineering&#xff09;和数学&#xff08;Mathematics&#xff09;的教育方法。这种教育模式旨在通过跨学科的方式培养学生的创新能力、问题解决能力…

MySQL 高级 - 第十四章 | 事务基础知识

目录 第十四章 事务基础知识14.1 数据库事务概述14.1.1 存储引擎支持情况14.1.2 基本概念14.1.3 事务的 ACID 特性14.1.4 事务的状态 14.2 如何使用事务14.2.1 显示事务14.2.2 隐式事务14.2.3 隐式提交数据的情况14.2.4 使用举例14.2.4.1 提交与回滚14.2.4.2 测试不支持事务的 …

Yarn:一个快速、可靠且安全的JavaScript包管理工具

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;还请三连支持一波哇ヾ(&#xff20;^∇^&#xff20;)ノ&#xff09; 目录 一、Yarn简介 二、Yarn的安装 1. 使用npm安装Yarn 2. 在macOS上…

11.redis的客户端-Jedis

1.Jedis 以redis命令作为方法名称&#xff0c;学习成本低&#xff0c;简单使用。但是jedis实例是不安全的&#xff0c;多线程环境下需要基于连接池来使用。 2.Lettuce lettuce是基于Netty实现的&#xff0c;支持同步&#xff0c;异步和响应式编程方式&#xff0c;并且是线程…

EmEditor 打开文档后光标如何默认定位到文档最后一行?

1、录制宏 &#xff08;1&#xff09;、点击工具栏上的红色录制宏按钮&#xff0c;开始录制宏。如图&#xff1a; &#xff08;2&#xff09;、按住快捷键Ctrl End快捷键&#xff0c;使光标跳转到文档末尾 &#xff08;3&#xff09;、完成录制后&#xff0c;再次点击录制按钮…

Hive SQL ——窗口函数源码阅读

前言 使用Starrocks引擎中的窗口函数 row_number() over( )对10亿的数据集进行去重操作&#xff0c;BE内存溢出问题频发&#xff08;忘记当时指定的BE内存上限是多少了.....&#xff09;&#xff0c;此时才意识到&#xff0c;开窗操作&#xff0c;如果使用 不当&#xff0c;反而…

stm32工程配置

目录 STM32F103 start&#xff1a;启动文件、内核寄存器文件、外设寄存器文件、时钟配置文件 library&#xff1a;标准库函数&#xff08;内核及外设驱动&#xff09; user&#xff1a;用户文件、库函数配置文件、中断程序文件 添加宏定义 STM32F407 start目录 启动文件…