用Python比较对象,你还在用==?



在这里插入图片描述

1.基础比较:== 和 is

  • 在Python中,对象间的比较是程序设计中的基础且重要的一环,它直接关系到数据处理的逻辑和效率。
  • 本章将深入探讨两种基本的比较操作符——==is ,通过实例解析它们的区别与应用场景。
①==:值的比较
  • ==操作符用于判断两个对象的值是否相等,即比较的是对象的内容。当两个对象的内容一致时,==返回True,反之则返回False
  • 这适用于各种基本类型如整数、字符串以及用户自定义类的对象,只要这些类实现了比较方法。
示例代码:
a = 5   
b = 5   
print(a == b)  # 输出: True      
str1 = "hello"   s
tr2 = "hello"   
print(str1 == str2)  # 输出: True      
class MyClass:       
def __init__(self, value):           
self.value = value      
obj1 = MyClass(10)   
obj2 = MyClass(10)   
print(obj1 == obj2)  # 默认情况下会比较地址,因此输出: False
②"id()"函数揭秘对象身份
  • id()函数返回对象的唯一标识符,即内存地址。结合“is” ,可以更直观理解对象的同一性。
示例:
a = 256   
b = 256   
print(id(a) == id(b))  # 输出可能为True ,因为小整数池的优化   
c = 257   
d = 257   
print(id(c) == id(d))  # 输出通常为False,除非偶然,每个新建的整数对象地址不同
  • 此例展示了Python对小整数的优化机制,以及id()在比较对象实体时的作用。
③is:身份的辨识
  • 不同于==对值的比较 ,is操作符用于检查两个变量是否引用同一个对象,即它们是否共享相同的内存地址。这意味着即使两个对象的内容相同,如果它们在内存中是独立创建的 ,is也会返回False
示例代码:
a = [1, 2, 3]   
b = a  # b指向a的同一份内存地址   
c = [1, 2, 3]      
print(a is b)  # 输出: True,因为a和b指向同一对象   
print(a is c)  # 输出: False,虽然内容相同,但a和c在内存中是不同的对象
  • 在处理单例模式、常量或者比较None时 ,is的使用尤为关键,因为它能确保比较的是对象的唯一性而非仅是值的等价性。
④实战演练:列表、字典的比较陷阱
  • 在处理复杂数据结构时 ,==is的区别尤为重要。特别是对于可变对象如列表和字典,浅比较可能导致意外结果。

列表比较陷阱

  • 考虑下面的例子:
g = [1, [2, 3]]   
h = [1, [2, 3]]   
print(g == h)  # 输出: True   
print(g is h)  # 输出: False
尽管gh的外层列表相等,但它们仍然是两个独立的列表对象。然而,当列表内包含其他列表或字典时,情况变得微妙:
i = [{'key': 'value'}]   
j = [{'key': 'value'}]   
print(i == j)  # 输出: True   
print(i is j)  # 输出: False
  • 尽管看起来ij的结构和内容一致 ,is仍然指出它们不是同一个对象。
  • 这是因为字典也是可变对象,即使内容相同,每次创建都会在内存中生成新的实例。
  • 通过上述对比,我们明确了==is在比较操作上的本质差异,这对于编写高效、逻辑严谨的Python代码至关重要。在实际应用中,合理选择比较方式能够有效避免潜在的逻辑错误和性能瓶颈。

2.深入理解比较操作符 🌀

  • 深入探究Python中的比较操作符,不仅限于简单的等于与不等于,还包括了更多元化的比较逻辑 ,为编写高效、灵活的代码提供了强大支持。
①不等号的妙用
  • 不等号包括<, >, <=, >=,它们在Python中用于数值、字符串以及可比较对象的顺序比较。利用这些操作符,开发者能够轻松地对集合中的元素进行排序、筛选等操作。
代码示例:
ages = [25, 30, 20, 35]   
sorted_ages = sorted(ages)  # 利用不等号逻辑进行排序   
print(sorted_ages)  # 输出: [20, 25, 30, 35]      
# 判断年龄是否在指定区间   
age = 27   
if 18 <= age < 60:       
print("符合工作年龄要求")  # 输出: 符合工作年龄要求
  • 通过上述示例 ,可以看到不等号在处理条件判断和数据排序时的实用性。
②成员资格in操作
  • in操作符用于检查一个值是否存在于序列(如列表、元组、字符串)或集合(如字典、集合)中 ,是判断成员资格的有力工具。此操作符不仅简化了代码逻辑 ,还提升了代码的可读性。
代码示例:
fruits = ['apple', 'banana', 'cherry']   
if 'banana' in fruits:       
print("香蕉在列表中")  # 输出: 香蕉在列表中          
# 集合示例   
numbers_set = {1, 2, 3, 4, 5}   
if 3 not in numbers_set:       
print("3不在集合中")   
else:       
print("3存在于集合中")  # 输出: 3存在于集合中
  • 通过in操作符,可以简洁明了地确认某个元素是否属于特定的数据结构,这对于条件分支逻辑尤其有用。
  • 掌握这些比较操作符,能够使你的Python代码更加灵活高效。

3.自定义比较:__eq__等魔法方法 🎩

  • 在Python中,通过覆盖特定的特殊方法(也称为“魔法方法”),我们可以自定义对象之间的比较行为。这为创建具有特定比较逻辑的自定义类提供了灵活性。
  • 本章将探讨如何重载比较操作以及详述丰富的比较方法(rich comparison methods)。
①重载比较操作
  • 重载比较操作通常从实现__eq__方法开始 ,该方法定义了当使用==操作符时的行为。此外,还可以实现__ne__(不等于),__lt__(小于),__le__(小于等于) ,__gt__(大于) ,和__ge__(大于等于)来覆盖完整的比较逻辑。
示例代码:自定义Person类,按年龄比较
class Person:       
def __init__(self, name, age):           
self.name = name           
self.age = age              
def __eq__(self, other):           
if isinstance(other, Person):               
return self.age == other.age           
return NotImplemented          
def __lt__(self, other):           
if isinstance(other, Person):               
return self.age < other.age           
return NotImplemented      # 使用示例   
person1 = Person("Alice", 30)   
person2 = Person("Bob", 25)      
print(person1 == person2)  # 输出: False   
print(person1 < person2)   # 输出: False   
print(person1 > person2)   # 由于未直接定义__gt__, 但__lt__和__eq__存在,Python可推导出结果: True
②rich comparison methods详述
  • Python的“富比较方法”包括__eq__, __ne__, __lt__, __le__, __gt__, 和 __ge__。当这些方法都被定义时,Python可以更智能地处理比较操作,无需显式地定义每一个比较逻辑。
  • 例如,如果实现了__lt____eq__,那么>>=操作也可以通过这些基础方法推导得出。
利用 functools.total_ordering 装饰器简化实现
  • 为了简化富比较方法的编写 ,Python标准库提供了functools.total_ordering装饰器,它可以根据已定义的一些比较方法自动推导出其他方法。
from functools 
import total_ordering      
@total_ordering   
class PersonRichCompare:       
def __init__(self, name, age):           
self.name = name           
self.age = age              
def __eq__(self, other):           
if isinstance(other, PersonRichCompare):               
return self.age == other.age           
return NotImplemented          
def __lt__(self, other):           
if isinstance(other, PersonRichCompare):               
return self.age < other.age           
return NotImplemented      # 现在,即使只定义了__eq__和__lt__,也能支持所有比较操作   
personA = PersonRichCompare("Charlie", 35)   
personB = PersonRichCompare("David", 30)      
print(personA >= personB)  # 输出: True
③实现不可变对象的比较
  • 对于不可变对象,确保一旦创建后其状态不再改变,是比较操作的理想选择。
  • 在定义这类对象时,除了__eq__ ,通常还会重写__hash__方法,以便对象可以用作字典键或集合成员。
示例代码:
class ImmutableObject:       
def __init__(self, value):           
self._value = value           
self.__hash = hash(value)          
def __eq__(self, other):           
if isinstance(other, ImmutableObject):               
return self._value == other._value           
return False          
def __hash__(self):           
return self.__hash      
obj3 = ImmutableObject(20)   
obj4 = ImmutableObject(20)   
print({obj3, obj4})  
# 输出: {<__main__.ImmutableObject object at 0x...>, <__main__.ImmutableObject object at 0x...>}   
# 注意:虽然obj3和obj4的值相等,但因为它们的id不同,集合中会保留两份,除非__hash__也重写以反映相等性
  • 注意,如果没有正确实现__hash__,即使__eq__表明两个对象相等 ,它们也可能作为不同元素出现在集合中。
④优化散列性能
  • 良好的散列函数应尽可能快地执行且能均匀分布不同对象的散列值,以减少哈希冲突,提高数据结构如字典的查找效率。
  • 对于自定义类,可以通过精心设计__hash__方法来优化散列性能。
优化技巧:
  • 简洁高效: 散列函数应尽量简单,避免复杂计算。
  • 利用内置类型: 如果对象属性是基本类型或已具备良好散列值的对象,可以直接使用这些值的散列。
  • 避免可变性: 确保用于计算散列值的属性在对象生命周期内不变,以保持散列值的稳定性。
  • 冲突最小化: 尽量让不同对象产生不同的散列值,减少碰撞。
例如 ,一个基于多个属性的简单散列函数实现:
class Person:       
def __init__(self, name, age):           
self.name = name           
self.age = age           
self.__hash = hash((self.name, self.age))          
def __eq__(self, other):           
if isinstance(other, Person):               
return (self.name, self.age) == (other.name, other.age)           
return False          
def __hash__(self):           
return self.__hash
  • 在设计__hash__时,确保遵循上述原则 ,可以有效提升涉及散列操作的代码性能。
  • 通过自定义比较逻辑,我们赋予了对象更加丰富的比较能力,这对于构建复杂的数据模型和算法设计尤为重要。正确实施这些魔法方法,可以显著增强代码的可读性和逻辑表达力。

4.高级技巧:functools.cmp_to_key 🧮

  • 在处理复杂排序需求时,Python的functools.cmp_to_key功能显得尤为重要。
  • 它允许我们将传统的比较函数转换为key函数 ,进而与内置的排序方法协同工作,特别是在需要自定义排序逻辑时。
  • 本章将展示如何利用这一高级技巧来优化自定义对象的排序过程。
①排序自定义对象
  • 直接使用sorted()或列表的.sort()方法时,它们默认采用对象的自然排序,即比较对象的值。
  • 然而,对于复杂对象 ,我们可能需要基于多个属性或自定义逻辑来决定排序顺序。
示例代码:未使用cmp_to_key的限制
  • 假设我们有以下Student类,希望通过成绩(grade)和姓名(name)进行排序 ,但由于Python 3中不再直接支持比较函数,直接排序会遇到障碍。
class Student:       
def __init__(self, name, grade):           
self.name = name           
self.grade = grade      
students = [Student("Alice", 88), Student("Bob", 95), Student("Charlie", 90)]   
# 直接尝试排序可能会导致TypeError,因为没有明确的比较规则   
# sorted(students, cmp=lambda x,y: (x.grade-y.grade) or (x.name > y.name))  
# Python 3已移除cmp参数
②cmp_to_key函数实战
  • 为了解决上述问题 ,我们可以定义一个比较函数,然后利用functools.cmp_to_key将其转化为适合sorted()或列表排序方法的key函数。
from functools 
import cmp_to_key      
def compare_students(s1, s2):       # 先按成绩降序,成绩相同则按姓名升序       
if s1.grade != s2.grade:           
return s2.grade - s1.grade  # 成绩降序       
else:           
return (s1.name > s2.name) - (s1.name < s2.name)  # 名字升序      
# 将比较函数转换为key函数   
key_func = cmp_to_key(compare_students)      # 实现排序   
sorted_students = sorted(students, key=key_func)   
for student in sorted_students:       
print(student.name, student.grade)
输出结果:
Bob 95   
Charlie 90   
Alice 88
  • 通过cmp_to_key ,我们不仅保留了自定义比较逻辑的灵活性,同时也兼容了现代Python的排序接口,使得对象排序更加灵活和高效。
  • 此技巧在处理复杂数据结构排序时尤为有用,大大增强了代码的可读性和扩展性。

5.实战应用:排序与过滤 🧹

  • 在Python编程实践中,数据的排序与过滤是日常任务中不可或缺的部分,它们直接影响到数据分析和处理的效率。
  • 本章将通过具体示例 ,介绍如何利用sorted()函数与列表的.sort()方法进行排序,以及如何借助filter()函数结合lambda表达式进行数据过滤。
①sorted()与list.sort()
  • sorted()函数:这是一个全局函数,可以对任何可迭代对象进行排序 ,返回一个新的排序后的列表 ,原列表保持不变。
  • list.sort()方法:这是列表对象的内置方法 ,直接在原列表上进行排序 ,改变原列表顺序 ,不返回任何值。
示例代码:使用sorted()排序字典列表
data = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]   
# 按照年龄从小到大排序   
sorted_data = sorted(data, key=lambda x: x["age"])   
print(sorted_data)
输出结果:
[{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
②filter()与lambda表达式
  • filter()函数用于过滤序列,构造一个由满足条件的元素组成的新迭代器。配合lambda表达式 ,可以简洁地定义过滤条件。
示例代码:使用filter()过滤出偶数
numbers = [1, 2, 3, 4, 5, 6]  
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))   
print(even_numbers)
输出结果:
[2, 4, 6]
  • 通过上述示例,我们看到sorted().sort()为数据提供了强大的排序能力,而filter()搭配lambda表达式则在数据过滤方面展现了其简洁高效的一面。
  • 这些工具的灵活运用 ,能极大提升处理数据集时的效率与便捷性。

6.比较器与key函数:字典排序 🔀

  • 在Python中,虽然字典本身是无序的,但自Python 3.7起 ,字典保持了插入顺序。不过,在需要根据特定键或值对字典进行排序时,我们可以利用sorted()函数结合key参数。
  • 本章将深入探讨如何使用key函数及itemgetterattrgetter工具来实现字典的排序。
①dict排序新特性
  • 虽然Python字典默认保持插入顺序,但直接排序依然需要借助外部函数。
  • 自Python 3.6开始 ,字典的这种插入顺序保证为许多应用场景提供了便利,但排序操作仍需额外步骤。
②itemgetter与attrgetter
  • operator模块提供的itemgetterattrgetter函数是高效获取对象属性或字典项的工具,它们在排序时尤其有用。
示例代码:使用itemgetter排序字典列表
from operator 
import itemgetter      # 假设有一个学生分数字典列表   
students_scores = [{'name': 'Alice', 'score': 88},{'name': 'Bob', 'score': 95},{'name': 'Charlie', 'score': 90},]      
# 按照'score'字段降序排序   
sorted_students = sorted(students_scores, key=itemgetter('score'), reverse=True)   
print(sorted_students)
输出结果:
[{'name': 'Bob', 'score': 95}, {'name': 'Charlie', 'score': 90}, {'name': 'Alice', 'score': 88}]
示例代码:使用attrgetter排序对象列表
  • 假设有一个自定义类Student,并有一系列学生对象的列表,我们想根据其score属性排序。
class Student:       
def __init__(self, name, score):           
self.name = name           
self.score = score      
students = [Student('Alice', 88),Student('Bob', 95),Student('Charlie', 90),]      
from operator 
import attrgetter      # 按'score'属性降序排序   
sorted_students = sorted(students, key=attrgetter('score'), reverse=True)   
for student in sorted_students:       
print(student.name, student.score)
输出结果:
Bob 95   
Charlie 90   
Alice 88
  • 通过上述示例,我们见识了如何利用itemgetterattrgetter高效地实现字典或对象列表的排序 ,它们不仅提高了代码的可读性 ,还优化了执行效率。
  • 这些工具在处理复杂数据排序时,展现了其独特的优势。

7.性能考量:时间复杂度与优化 💨

  • 在Python编程中,优化比较操作和选择合适的数据结构对于提升程序性能至关重要。
  • 本章将探讨比较操作的效率影响,以及如何依据具体需求选择最适宜的数据结构,从而达到提高执行效率的目的。
①比较操作的效率
  • 比较操作的效率直接关系到算法的运行速度,尤其是在大规模数据处理场景下。
  • Python中的比较操作通常被认为是O(1)的时间复杂度 ,意味着比较两个值的时间是恒定的 ,不受数据规模影响。然而,当比较操作涉及复杂对象或深层次嵌套结构时,效率可能会下降。优化策略包括减少不必要的比较、利用缓存存储中间结果,以及选择高效的比较逻辑。
示例代码:避免重复比较
  • 考虑一个场景 ,需要频繁比较列表中的元素是否出现在另一个列表中,可通过构建集合来优化查找效率。
list1 = [1, 2, 3, 4, 5]   
list2 = [3, 4, 5, 6, 7]      
set_list1 = set(list1)   
filtered_list = [item for item in list2 if item in set_list1]   
print(filtered_list)
输出结果:
[3, 4, 5]
②选择合适的数据结构
  • 正确选择数据结构可以显著提升程序性能。例如 ,当涉及到频繁查找时,哈希表(如字典或集合)比列表更为高效;而有序数据的快速查找和插入操作则更适合使用平衡树结构(如内置的sortedlist模块或btree模块)。
示例代码:使用字典进行高效查找
# 假设有一系列学生数据 ,经常需要根据学生ID快速查找学生信息   
students = {
1: {'name': 'Alice', 'age': 20},       
2: {'name': 'Bob', 'age': 22},# ...   }      
student_id = 1   
print(students.get(student_id, "Not Found"))
输出结果:
{'name': 'Alice', 'age': 20}
  • 在设计程序时,深入理解数据的操作模式并据此选择合适的数据结构 ,是提升代码性能的关键步骤。通过上述示例,我们看到了合理利用数据结构和优化比较策略对提高程序效率的重要性。

总结 🎯

  • 本文全面探讨了Python中对象比较的深度知识,从基础的==is区别,到不等号与成员资格操作符的实践 ,进一步讲解自定义比较逻辑通过__eq__等魔法方法的实现细节。
  • 文章深入到高级技巧,如使用functools.cmp_to_key优化排序逻辑,以及如何在实际场景中运用sorted()filter()等函数进行高效排序与过滤。
  • 此外 ,探讨了字典排序的新特性及itemgetterattrgetter的妙用,并在性能优化章节中强调了比较操作效率与恰当数据结构选择的重要性。
  • 综上所述,本文为Python开发者提供了关于对象比较的全方位指导 ,旨在提升代码性能与逻辑严谨性,助力高效数据处理与算法设计。
    图片

总结

  • 最后希望你编程学习上不急不躁,按照计划有条不紊推进,把任何一件事做到极致,都是不容易的,加油,努力!相信自己!

文末福利

  • 最后这里免费分享给大家一份Python全套学习资料,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以和我一起来学习交流呀。

包含编程资料、学习路线图、源代码、软件安装包等!【[点击这里]】领取!

  • ① Python所有方向的学习路线图,清楚各个方向要学什么东西
  • ② 100多节Python课程视频,涵盖必备基础、爬虫和数据分析
  • ③ 100多个Python实战案例,学习不再是只会理论
  • ④ 华为出品独家Python漫画教程,手机也能学习

可以扫描下方二维码领取【保证100%免费

在这里插入图片描述

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

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

相关文章

MySQL 中的集群部署方案

文章目录 MySQL 中的集群部署方案MySQL ReplicationMySQL Group ReplicationInnoDB ClusterInnoDB ClusterSetInnoDB ReplicaSetMMMMHAGalera ClusterMySQL ClusterMySQL Fabric 总结参考 MySQL 中的集群部署方案 MySQL Replication MySQL Replication 是官方提供的主从同步方…

Vision Pro空间叙事创作工具:开启多媒体融合新纪元

在数字内容创作领域迎来了一位新玩家——专为Apple Vision Pro设计的空间叙事创作工具。这款工具不仅是一个沉浸式内容分享平台&#xff0c;更是面向空间计算时代的内容创作解决方案&#xff0c;它旨在通过全新的多媒体融合方式&#xff0c;打破传统内容创作的界限。 产品优势…

屏幕水印是什么,怎么设置丨超级简单的防盗水印教程来了,包教包会!

小李&#xff1a;现在科技这么发达&#xff0c;随便一截图或者拍照&#xff0c;信息就满天飞了 小张&#xff1a;给你的电脑屏幕安排一件“隐形战衣”呗 小李&#xff1a;哦&#xff1f;新词儿&#xff1f;些许陌生 小张&#xff1a;简而言之&#xff0c;言而简之&#xff0…

css:没错又是我

背景 给元素添加背景样式 还可以设置背景颜色、背景图片&#xff08;教练我要学这个&#xff09;、背景平铺、背景图片位置、背景图像固定 背景颜色 这个我们用过&#xff0c;就是&#xff1a; a {background-color: hotpink; } 一般默认值是transparent&#xff0c;也就…

adb 如何通过wifi连接手机

1. 电脑通过USB线连接手机 1.1手机开启开发者模式 以小米手机为例&#xff1a;连续点击OS版本系统&#xff08;设置–>我的设备–>全部参数&#xff09; 1.2在开发者模式下&#xff0c;启动允许USB安装与USB调试 操作步骤&#xff1a;设置>更多设置>开发者选项&g…

自己开发得期货资管模拟软件演示1.0.15版仅供学习

期货资管模拟软件演示1.0.15版仅供学习——C技术栈知识分享 本文将以期货资管模拟软件演示1.0.15版为例&#xff0c;分享其基于C技术栈的框架知识。 一、C技术栈在期货交易软件开发中的应用 C作为一种高性能的编程语言&#xff0c;以其强大的内存管理能力和高效的执行速度&a…

浅谈单片机的gcc优化级别__以双音频信号发生器为例

IDE&#xff1a; CLion HOST&#xff1a; Windows 11 MinGW&#xff1a;x86_64-14.2.0-release-posix-seh-ucrt-rt_v12-rev0 GCC&#xff1a; arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi 一、简介 gcc有多种优化级别&#xff0c;一般不选择的情况下&#x…

C++之继承多态

C之继承&多态 继承继承之形继承的作用域继承的构造与析构多继承菱形继承 多态多态之形final和override(C11)纯虚函数&抽象类多态的原理打印虚表&#xff08;在vs2022中&#xff09;多继承下的虚表菱形虚继承中埋的坑静态多态与动态多态我对虚函数和普通成员函数调用区别…

机器学习-36-对ML的思考之机器学习研究的初衷及科学研究的期望

文章目录 1 机器学习最初的样子1.1 知识工程诞生(专家系统)1.2 知识工程高潮期1.3 专家系统的瓶颈(知识获取)1.4 机器学习研究的初衷2 科学研究对机器学习的期望2.1 面向科学研究的机器学习轮廓2.2 机器学习及其应用研讨会2.3 智能信息处理系列研讨会2.4 机器学习对科学研究的重…

arm 汇编技巧

汇编标号&#xff1a;f表示forward&#xff0c; b表示backward&#xff1a; Here is an example: 1: branch 1f 2: branch 1b 1: branch 2f 2: branch 1b Which is the equivalent of: label_1: branch label_3 label_2: branch label_1 label_3: branch label_4 label_4: bra…

特色3D打印stm32迷你8轴双核心主板

我自己设计的3D打印机主板 1. 这是一块迷你的8轴主板, 主板尺寸为100mm*75mm, 使用一个8cm静音风扇散热足够了2. 这是一个带有保护的板子, 驱动上的gpio具有过压保护功能, 能够直接抗住24V的冲击, 意味着一个驱动炸了, 板子不烧, 并且其他的驱动也没事, 主板支持自动关机3. 8…

golang分布式缓存项目 Day2 单机并发缓存

注&#xff1a;该项目原作者&#xff1a;https://geektutu.com/post/geecache-day1.html。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习。 支持并发读写 接下来我们使用 sync.Mutex 封装 LRU 的几个方法&#xff0c;使之支持并发的读写。在这之…

2024 年将 Swagger 导入 Postman 图文教程

2024 年将 Swagger 导入 Postman 图文教程

从入门到精通:hello-algo开源项目助你系统学习数据结构与算法

文章目录 前言1.关于hello-algo2.安装Docker和Docker compose3.本地部署hello-algo4. hello-algo本地访问5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 本文将探讨如何在本地环境中部署hello-algo这一算法学习必备项目&#xff0c;并利用cp…

SystemVerilog学习笔记(七):函数与任务

函数 函数的主要用途是编写一段可以随时调用n次的代码&#xff0c;只需调用函数名即可&#xff0c;不需要任何模拟时间来执行。函数是返回类型&#xff0c;仅返回函数声明中提到的单个值&#xff0c;如果未声明则返回一个位的值。 语法&#xff1a; initial begin functio…

地下水数值模拟、 地下水环评、Visual modflow Flex、Modflow

地下水数值模拟软件Visual modflow Flex实践技术应用 地下水数值模拟软件的应用&#xff0c;主要围绕的目前应用较为广泛的Visual Modflow Flex 6.1软件版本开展&#xff0c;结合具体应用场景&#xff0c;实例讲解软件的全流程应用过程&#xff0c;包括数据处理分析、数值模型…

丹摩征文活动|Llama3.1:从安装到熟练使用的全方位教程

0.前言 目前关于 Llama 3.1 的详细安装和使用指南在网络上较为分散&#xff0c;对于许多想要深入了解和应用该模型的人来说&#xff0c;缺乏一个系统、全面的指导资料。为了填补这一空白&#xff0c;本文应运而生。旨在为广大读者提供从 Llama 3.1 的安装到熟练使用的全方位指…

UI自动化测试|CSS元素定位实践

前言 自动化测试元素定位是指在自动化测试过程中&#xff0c;通过特定的方法或策略来准确识别和定位页面上的元素&#xff0c;以便对这些元素进行进一步的操作或断言。这些元素可以是文本框、按钮、链接、图片等HTML页面上的任何可见或不可见的组件。 在自动化测试中&#xf…

软件架构与模式分析

软件架构模式分析 软件架构模式和架构风格是两个相关但不同的概念。 软件架构模式&#xff08;Software Architecture Patterns&#xff09;是一种在软件工程领域广泛应用的规范化、可复用的架构设计方案。它是通过抽象和提炼出解决特定问题所需的结构、组件、关系和规则等&am…

npm完整发包流程(亲测可验证)

1. 准备工作 &#xff08;1&#xff09; 在npm官网上注册一个账号 &#xff08;2&#xff09; 注册成功之后&#xff0c;npm会发送一封邮件给你&#xff0c;点击邮件里面的链接&#xff0c;做确认关联操作&#xff08;必需&#xff09; 2. 创建自己的npm包 &#xff08;…