Python-VBA函数之旅-property函数

目录

一、property函数的常见应用场景

二、property函数使用注意事项

三、如何用好property函数?

1、property函数:

1-1、Python:

1-2、VBA:

2、推荐阅读:

个人主页:神奇夜光杯-CSDN博客 

  

一、property函数的常见应用场景

        在Python中,property()函数(或更常见的是@property装饰器)的实际应用场景非常广泛,主要用于封装类的内部状态并提供对外的访问接口,常见的应用场景有:

1、隐藏内部实现细节:通过getter和setter方法,我们可以隐藏对象的内部状态,只暴露必要的接口给外部调用者,这有助于保护对象的状态不被随意修改,同时也使得代码更加易于理解和维护。

2、添加属性验证:在setter方法中,我们可以添加对属性值的验证逻辑。例如,我们可以确保一个年龄属性总是大于0,或者一个邮箱地址属性总是符合某种格式。

3、计算属性:有些属性可能不是直接存储在对象的状态中的,而是需要基于其他属性计算得出,通过使用property,我们可以将这样的属性表示为对象的一个“正常”属性,而无需调用一个方法来获取它。

4、延迟计算:对于某些计算成本较高的属性,我们可能希望在第一次访问时才进行计算,并将结果缓存起来,通过使用property和内部变量,我们可以实现这样的延迟计算。

5、访问控制: property()函数允许你控制对属性的访问权限。例如,你可以使属性只读,或者只允许在特定条件下修改属性。

6、简化接口:在某些情况下,你可能想要隐藏对象的内部复杂性,只向外部提供一个简洁的接口,使用property可以将内部方法(如getter、setter)暴露为看起来像普通属性的接口。

7、实现数据绑定:在更复杂的场景中,property可以与观察者模式(Observer Pattern)或数据绑定库结合使用,以实现当属性发生变化时自动触发某些操作或更新UI等效果。

8、线程安全:在多线程环境中,对属性的直接访问可能会导致数据竞争或其他并发问题,使用property可以确保在访问或修改属性时执行必要的同步操作,从而保证线程安全。

9、日志记录或监控:在获取或设置属性时,你可能想要记录一些信息(如访问时间、访问者等),或者触发某些监控事件,通过property可以轻松实现这些功能。

10、惰性加载:对于某些需要大量计算或需要从外部资源(如数据库或网络)加载的属性,可以使用property实现惰性加载,这意味着属性只有在首次被访问时才会进行计算或加载,从而节省资源。

二、property函数使用注意事项

        在Python中,property()函数是一个内置函数,用于在新式类中返回属性值property()函数允许你定义getter,setter和deleter方法,这些方法分别用于获取、设置和删除对象的属性。以下是在使用property()函数时需要注意的一些事项:

1、定义getter/setter/deleter方法:getter方法通常不需要任何参数,并返回属性的值;setter方法需要接收两个参数:self和要设置的值value;deleter方法只需要self参数。   

示例:
   class Circle:
       def __init__(self, radius=1.0):
           self._radius = radius

       @property
       def radius(self):
           return self._radius

       @radius.setter
       def radius(self, value):
           if value < 0:
               raise ValueError("Radius cannot be negative")
           self._radius = value

       @radius.deleter
       def radius(self):
           del self._radius

2、私有属性:当你使用@property装饰器时,通常建议将实际存储数据的属性设为私有(例如使用下划线前缀),以避免直接访问和修改它们。

3、装饰器语法:你可以使用装饰器语法来定义getter,setter和deleter方法;另一种语法是使用property()函数直接返回getter,setter和deleter方法作为元组,但这种方法较少使用,因为它不够直观。

4、性能:虽然property()通常不会成为性能瓶颈,但在需要处理大量对象的场合中,频繁地调用getter或setter可能会产生一些开销,在这种情况下,你可能需要考虑其他方法,如使用@cached_property装饰器(来自cached_property库或类似库)来缓存getter方法的返回值。

5、线程安全:如果你在多线程环境中使用setter或deleter方法,并且这些方法可能会修改共享状态,那么你需要确保这些方法是线程安全的。

6、错误处理:在setter方法中,你可能需要添加错误处理逻辑来确保设置的值是有效的。

7、文档字符串:为getter,setter和deleter方法提供文档字符串是一个好习惯,这有助于其他开发者理解这些方法的作用和用法。

8、可读性:当使用property()函数时,确保你的getter,setter和deleter方法的命名清晰易懂,以便其他开发者能够轻松理解你的代码。

9、继承:虽然property()函数提供了更好的封装和抽象,但它也带来了一定的开销,因为每次访问属性时都会调用一个方法,然而,在大多数情况下,这种开销是可以接受的,因为Python方法调用的开销相对较低。

10、向后兼容性:如果你的类需要向后兼容Python 2,请注意property()函数在Python 2和Python 3中的行为可能略有不同:在Python 2中,property()是一个内置的工厂函数;而在Python 3中,它不仅是一个内置函数,也可以用作装饰器。

三、如何用好property函数?

        在Python中,property()函数是一个内置函数,用于创建只读的、可写的或可删除的属性,这提供了一种将方法作为属性访问的方式,从而简化了对对象属性的访问和修改。

property()函数的基本用法有三种:

1、只读属性:只需要定义一个getter方法。

class MyClass:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

obj = MyClass(10)
print(obj.value)  # 输出: 10

在这个例子中,`value` 是一个只读属性,只能通过 `obj.value` 来访问,但不能直接赋值。

2、可读写属性:除了getter方法,还需要定义一个setter方法。

class MyClass:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new_value):
        if new_value < 0:
            raise ValueError("Value must be non-negative")
        self._value = new_value

obj = MyClass(10)
print(obj.value)  # 输出: 10
obj.value = 20
print(obj.value)  # 输出: 20
obj.value = -1    # 抛出 ValueError

在这个例子中,`value` 是一个可读写属性,可以通过 `obj.value` 来访问,也可以通过 `obj.value = new_value` 来修改,在setter方法中,我们还添加了一个简单的验证逻辑。

3、可删除属性:除了getter和setter方法,还需要定义一个deleter方法。

class MyClass:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new_value):
        self._value = new_value

    @value.deleter
    def value(self):
        del self._value
obj = MyClass(10)
print(obj.value)  # 输出: 10
obj.value = 20
print(obj.value)  # 输出: 20
del obj.value
# 尝试访问 obj.value 将引发 AttributeError

在这个例子中,`value` 是一个可删除的属性,可以使用 `del obj.value` 来删除它。

注意:虽然property()函数可以直接使用,但通常建议使用@property、@value.setter和 @value.deleter装饰器来定义属性,因为它们更加简洁和易读。

1、property函数:
1-1、Python:
# 1.函数:property
# 2.功能:用于创建属性实例,这些实例可以绑定到类的方法上,从而允许我们像访问数据属性一样访问类的方法
# 3.语法:property([fget=None[, fset=None[, fdel=None[, doc=None]]]])
# 4.参数:
# 4-1、fget:用于获取属性值的方法(getter),它应该是一个不带参数的方法,并且返回一个值;如果省略,则属性为只读
# 4-2、fset:用于设置属性值的方法(setter),它应该是一个接受一个参数(新值)的方法,并且不返回任何内容(或者返回None);如果省略,则属性为只读
# 4-3、fdel:用于删除属性的方法(deleter),它应该是一个不带参数的方法,并且不返回任何内容(或者返回None);如果省略,则不能删除属性
# 4-4、doc:一个可选的字符串,作为属性的文档字符串,如果省略,则使用`fget`、`fset`或`fdel`方法中的文档字符串(如果存在的话)
# 5.返回值:返回类的属性
# 6.说明:
# 6-1、如果给出doc参数,doc将成为该property属性的文档字符串;否则该property将复制fget/fset/fdel等方法中的文档字符串(如果存在的话)
# 7.示例:
# 用dir()函数获取该函数内置的属性和方法
print(dir(property))
# ['__class__', '__delattr__', '__delete__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__',
# '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__isabstractmethod__', '__le__', '__lt__',
# '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__set__', '__set_name__', '__setattr__', '__sizeof__',
# '__str__', '__subclasshook__', 'deleter', 'fdel', 'fget', 'fset', 'getter', 'setter']

# 用help()函数获取该函数的文档信息
help(property)

# 应用一:隐藏内部实现细节
class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        """Getter for radius."""
        return self._radius

    @radius.setter
    def radius(self, value):
        """Setter for radius, checks if value is positive."""
        if value < 0:
            raise ValueError("Radius cannot be negative.")
        self._radius = value

    @property
    def diameter(self):
        """Calculate and return the diameter."""
        return 2 * self._radius

    @property
    def area(self):
        """Calculate and return the area."""
        import math
        return math.pi * (self._radius ** 2)
# 注意:diameter和area是只读的,因为它们没有setter方法
# 使用Circle类
c = Circle(5)
print(c.radius)  # 访问radius属性
print(c.diameter)  # 访问diameter属性(只读)
print(c.area)  # 访问area属性(只读)
# 5
# 10
# 78.53981633974483

c.radius = 10  # 修改radius属性
print(c.radius)  # 再次访问radius属性,确认已修改
print(c.diameter)  # 再次访问diameter属性,确认已根据新的radius更新
print(c.area)  # 再次访问area属性,确认已根据新的radius更新
# 10
# 20
# 314.1592653589793

# 尝试设置直径或面积(这将失败,因为它们没有setter方法)
# c.diameter = 15  # 这会抛出一个 AttributeError
# c.area = 50      # 这也会抛出一个 AttributeError
# AttributeError: property 'diameter' of 'Circle' object has no setter

# 应用二:添加属性验证
class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = None
        self.age = age  # 使用setter方法进行初始化

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        """Getter for age."""
        return self._age

    @age.setter
    def age(self, value):
        """Setter for age, checks if value is a positive integer."""
        if not isinstance(value, int) or value < 0:
            raise ValueError("Age must be a positive integer.")
        self._age = value

    # 如果你想要一个deleter方法,可以添加如下:
    @age.deleter
    def age(self):
        raise AttributeError("Cannot delete the age attribute.")
# 使用 Person 类
try:
    p = Person("Myelsa", 18)
    print(p.name)  # 输出: Myelsa
    print(p.age)  # 输出: 18

    p.age = 42  # 修改age属性
    print(p.age)  # 输出: 42

    # 尝试设置不合法的age值
    p.age = -1  # 抛出 ValueError
    # p.age = "fourty two"  # 也会抛出ValueError
except ValueError as e:
    print(e)
# Myelsa
# 18
# 42
# Age must be a positive integer.

# 尝试删除age属性(如果已定义deleter)
del p.age  # 如果 deleter 存在且未抛出AttributeError,则会执行
# 否则,上面的代码会按原样运行,因为deleter抛出了AttributeError
# AttributeError: Cannot delete the age attribute.

# 应用三:计算属性
class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    @property
    def width(self):
        """Getter for width."""
        return self._width

    @width.setter
    def width(self, value):
        """Setter for width."""
        if value < 0:
            raise ValueError("Width cannot be negative.")
        self._width = value

    @property
    def height(self):
        """Getter for height."""
        return self._height

    @height.setter
    def height(self, value):
        """Setter for height."""
        if value < 0:
            raise ValueError("Height cannot be negative.")
        self._height = value

    @property
    def area(self):
        """Calculate and return the area."""
        return self._width * self._height

    @property
    def perimeter(self):
        """Calculate and return the perimeter."""
        return 2 * (self._width + self._height)

# 使用Rectangle类
rect = Rectangle(5, 10)
print(rect.area)  # 输出: 50 (宽度5乘以高度10)
print(rect.perimeter)  # 输出: 30 (两倍的(宽度5加高度10))

rect.width = 7
print(rect.area)  # 输出: 70 (新的宽度7乘以高度10)
print(rect.perimeter)  # 输出: 34 (两倍的(新的宽度7加高度10))
# 50
# 30
# 70
# 34

# 应用四:延迟计算
class Circle:
    def __init__(self, radius):
        self._radius = radius
        self._area = None
        self._circumference = None

    @property
    def radius(self):
        """Getter for radius."""
        return self._radius

    @radius.setter
    def radius(self, value):
        """Setter for radius."""
        if value < 0:
            raise ValueError("Radius cannot be negative.")
        self._radius = value
        # 当半径改变时,重置缓存的area和circumference
        self._area = None
        self._circumference = None

    @property
    def area(self):
        """Calculate and cache the area."""
        if self._area is None:
            self._area = 3.14159 * self._radius ** 2
        return self._area

    @property
    def circumference(self):
        """Calculate and cache the circumference."""
        if self._circumference is None:
            self._circumference = 2 * 3.14159 * self._radius
        return self._circumference
# 使用 Circle 类
circle = Circle(5)
print(circle.area)  # 首次访问,进行计算并缓存结果
print(circle.circumference)  # 首次访问,进行计算并缓存结果

# 再次访问,直接从缓存中获取结果
print(circle.area)  # 输出与之前相同,因为结果是缓存的
print(circle.circumference)  # 输出与之前相同,因为结果是缓存的

circle.radius = 7
print(circle.area)  # 半径改变,重新计算并缓存新的area
print(circle.circumference)  # 半径改变,重新计算并缓存新的circumference
# 78.53975
# 31.4159
# 78.53975
# 31.4159
# 153.93791
# 43.98226

# 应用五:访问控制
class AccessControlled:
    def __init__(self, value):
        self._value = value

    def get_value(self):
        """Getter for value."""
        # 在这里可以添加访问前的验证或逻辑
        print("Reading value...")
        return self._value

    def set_value(self, value):
        """Setter for value."""
        # 在这里可以添加设置前的验证或逻辑
        if value < 0:
            raise ValueError("Value cannot be negative.")
        print("Setting value...")
        self._value = value

    def del_value(self):
        """Deleter for value."""
        # 在这里可以添加删除前的验证或逻辑
        print("Deleting value...")
        del self._value
    # 使用property()将方法绑定到属性
    value = property(get_value, set_value, del_value, "This is a controlled access value.")
# 使用AccessControlled类
obj = AccessControlled(10)
# 读取属性值
print(obj.value)  # 输出: Reading value... 10
# 设置属性值
obj.value = 20
# 输出: Setting value...
# 尝试设置不合法的属性值
try:
    obj.value = -5
except ValueError as e:
    print(e)  # 输出: Value cannot be negative.
# 删除属性值
del obj.value
# 输出: Deleting value...
# 尝试访问已删除的属性值
try:
    print(obj.value)
except AttributeError:
    print("Value has been deleted.")  # 输出: Value has been deleted.
# Reading value...
# 10
# Setting value...
# Value cannot be negative.
# Deleting value...
# Reading value...
# Value has been deleted.

# 应用六:简化接口
class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    @property
    def width(self):
        """Getter for width."""
        return self._width

    @width.setter
    def width(self, value):
        """Setter for width."""
        if value < 0:
            raise ValueError("Width cannot be negative.")
        self._width = value

    @property
    def height(self):
        """Getter for height."""
        return self._height

    @height.setter
    def height(self, value):
        """Setter for height."""
        if value < 0:
            raise ValueError("Height cannot be negative.")
        self._height = value

    @property
    def area(self):
        """Calculate and return the area of the rectangle."""
        return self._width * self._height

    @property
    def perimeter(self):
        """Calculate and return the perimeter of the rectangle."""
        return 2 * (self._width + self._height)
# 使用 Rectangle 类
rect = Rectangle(5, 10)

# 访问属性,无需关心内部计算
print(rect.area)  # 输出: 50
print(rect.perimeter)  # 输出: 30

# 设置属性
rect.width = 7
rect.height = 8

# 再次访问属性
print(rect.area)  # 输出: 56
print(rect.perimeter)  # 输出: 30

# 尝试设置不合法的属性值
try:
    rect.width = -5
except ValueError as e:
    print(e)  # 输出: Width cannot be negative.
# 50
# 30
# 56
# 30
# Width cannot be negative.

# 应用七:实现数据绑定
class DataBinder:
    def __init__(self, initial_value, callback=None):
        self._value = initial_value
        self._callback = callback

    @property
    def value(self):
        """Getter for value."""
        return self._value

    @value.setter
    def value(self, new_value):
        """Setter for value. Triggers the callback if provided."""
        self._value = new_value
        if self._callback:
            self._callback(new_value)

# 定义一个回调函数来模拟数据绑定的效果
def on_value_change(new_value):
    print(f"Value has changed to: {new_value}")
# 使用 DataBinder 类并设置回调函数
binder = DataBinder(10, on_value_change)

# 访问属性值
print(binder.value)  # 输出: 10

# 修改属性值,这会触发回调函数
binder.value = 20
# 输出: Value has changed to: 20

# 再次修改属性值
binder.value = 30
# 输出: Value has changed to: 30

# 应用八:线程安全
import threading
class ThreadSafeClass:
    def __init__(self):
        self._value = 0
        self._lock = threading.Lock()

    @property
    def value(self):
        """线程安全的getter方法"""
        with self._lock:
            return self._value

    @value.setter
    def value(self, new_value):
        """线程安全的setter方法"""
        with self._lock:
            self._value = new_value
# 使用示例
if __name__ == "__main__":
    # 创建一个ThreadSafeClass的实例
    obj = ThreadSafeClass()
    # 假设我们有两个线程,它们将尝试同时访问和修改obj.value
    def worker(obj, name, increment):
        for _ in range(100000):  # 假设我们进行大量操作以突出线程安全问题
            with obj._lock:  # 在这里,我们只是为了演示而手动加锁,但在实际setter/getter中不需要
                old_value = obj.value
                new_value = old_value + increment
                obj.value = new_value
            print(f"{name}: Value after increment is {obj.value}")
    # 创建两个线程
    t1 = threading.Thread(target=worker, args=(obj, "Thread 1", 1))
    t2 = threading.Thread(target=worker, args=(obj, "Thread 2", -1))
    # 启动线程
    t1.start()
    t2.start()
    # 等待线程完成
    t1.join()
    t2.join()
    # 输出最终值(可能不是0,因为线程调度是随机的,但每次操作都是线程安全的)
    print(f"Final value: {obj.value}")

# 应用九:日志记录或监控
import logging
class LoggedPropertyClass:
    def __init__(self):
        self._value = None
        self._logger = logging.getLogger(__name__)
        self._logger.setLevel(logging.INFO)

        # 创建一个handler,用于写入日志文件
        fh = logging.FileHandler('property_log.log')
        fh.setLevel(logging.INFO)

        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)

        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        # 给logger添加handler
        self._logger.addHandler(fh)
        self._logger.addHandler(ch)

    @property
    def value(self):
        """Getter方法,用于访问_value属性,并添加日志记录"""
        self._logger.info("Accessing value: %s", self._value)
        return self._value

    @value.setter
    def value(self, new_value):
        """Setter方法,用于设置_value属性,并添加日志记录"""
        self._logger.info("Setting value to: %s", new_value)
        self._value = new_value

# 使用示例
if __name__ == "__main__":
    obj = LoggedPropertyClass()
    obj.value = 42  # 这将触发setter方法并记录日志
    print(obj.value)  # 这将触发getter方法并记录日志
# 42
# 2024-05-07 18:46:57,919 - __main__ - INFO - Setting value to: 42
# 2024-05-07 18:46:57,919 - __main__ - INFO - Accessing value: 42

# 应用十:惰性加载
class LazyLoadedClass:
    def __init__(self):
        # 初始化时,我们不立即加载数据,而是设置一个标记
        self._data = None
        self._loaded = False

    @property
    def data(self):
        """惰性加载的getter方法"""
        if not self._loaded:
            # 模拟数据加载过程,这里可以替换为实际的数据加载逻辑
            self._data = self._load_data()
            self._loaded = True
        return self._data

    def _load_data(self):
        """模拟的数据加载函数"""
        # 这里可以放置实际的加载逻辑,比如从数据库、文件或网络请求中获取数据
        # 这里我们只是简单地返回一个固定的值作为示例
        print("Loading data...")
        return "Loaded data"

# 使用示例
if __name__ == "__main__":
    obj = LazyLoadedClass()
    print(obj.data)  # 第一次访问,会加载数据并打印"Loading data...",然后返回"Loaded data"
    print(obj.data)  # 第二次访问,因为数据已经被加载和缓存,所以不会再次加载,直接返回"Loaded data"
# Loading data...
# Loaded data
# Loaded data
1-2、VBA:
略,待后补。
2、推荐阅读:

2-1、Python-VBA函数之旅-open()函数

Python算法之旅:Algorithm

Python函数之旅:Functions

个人主页:神奇夜光杯-CSDN博客 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

信创发展之路

1、什么是信创 信创,即信息技术应用创新,以前也被称为“安可“(安全可控) 1.1、基本概念 信创产业主要包括四大领域: 基础设施,包括芯片(CPU、GPU等)、存储、服务器、云计算等;基础软件,包括操作系统、数据库、中间件等;应用软件,包括基础办公软件、企业管理软件(…

CRM定义是什么?

CRM&#xff0c;即客户关系管理&#xff0c;是一种综合性的管理策略&#xff0c;旨在通过一系列技术手段和业务流程&#xff0c;建立、维护和优化企业与客户之间的关系。它不仅仅是一种技术工具&#xff0c;更是一种以客户为中心商业哲学&#xff0c;是现代企业提升竞争力、实现…

文心一言 VS 讯飞星火 VS chatgpt (254)-- 算法导论18.2 7题

七、假设磁盘硬件允许我们任意选择磁盘页面的大小&#xff0c;但读取磁盘页面的时间是 abt 其中 a 和 b 为规定的常数&#xff0c;t 为确定磁盘页大小后的 B 树的最小度数。请描述如何选择 t 以(近似地)最小化 B 树的查找时间。对 a5ms 和 b10ms &#xff0c;请给出 t 的一个最…

深度学习之基于Matlab神经网络的活体人脸和视频人脸识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 人脸识别技术作为生物识别技术的一种&#xff0c;近年来得到了广泛的关注和应用。与传统的身份认证方…

【贪心算法】单源最短路径Python实现

文章目录 [toc]问题描述Dijkstra算法Dijkstra算法的正确性贪心选择性质最优子结构性质 Dijkstra算法应用示例Python实现时间复杂性 问题描述 给定一个带权有向图 G ( V , E ) G (V , E) G(V,E)&#xff0c;其中每条边的权是非负实数&#xff0c;给定 V V V中的一个顶点&…

Vue2之路由跳转传参中文问题处理

Vue2之路由跳转传参中文问题处理 文章目录 Vue2之路由跳转传参中文问题处理1. 问题描述1. 当前vue组件2. 跳转到的vue组件3. 出现的错误 2. 解决方法1. 当前vue组件2. 跳转到的vue组件 1. 问题描述 在el-table中的记录列表中放置了一个 操作按钮&#xff0c;点这个按钮时可以新…

Python网络协议socket

01 协议基础 01 网络协议 协议&#xff1a;一种规则 网络协议&#xff1a;网络规则&#xff0c;一种在网络通信中的数据包的数据规则 02 TCP/IP协议 osi模型 tcp/ip协议 03 tcp协议 TCP协议提供了一种端到端的、基于连接的、可靠的通信服务。 三次握手 创建连接 四次挥手…

铜价飙升,慧能泰HUSB332F带你狂飙

铜价&#xff0c;近期涨的很飘&#xff0c;涨到怀疑人生。继黄金后&#xff0c;铜成了另一个疯涨的明星&#xff01;作为电线电缆生产不可或缺的原材料&#xff0c;铜的身价暴涨直接拉响了成本警报&#xff0c;压缩了企业的利润空间。众多电线电缆制造商面临着严峻的挑战与考验…

LeetCode-DFS-树类-简单难度

关于二叉树的相关深度优先遍历类题目&#xff0c;重点在于掌握最基本的前中后序遍历&#xff0c;大多数题目都在围绕这套逻辑&#xff0c;找到处理节点的时机&#xff0c;以及停止遍历的条件&#xff0c;即可顺利完成。 二叉树前中后序遍历模板 所谓前中后序&#xff0c;指的…

蓝桥杯备赛(填空题)【Python B组】

一、弹珠堆放 问题描述 小蓝有 20230610 颗磁力弹珠&#xff0c;他对金字塔形状尤其感兴趣&#xff0c;如下图所示&#xff1a; &#xff08;图是盗来的啊&#xff0c;侵权请联系删除&#xff09; 问题分析 找规律&#xff0c;第一层1个&#xff0c;第二层3个&#xff0c;第…

预定类小程序源码搭建包含各行业+源码开源可二开+详细图文搭建部署教程

在数字化浪潮席卷的今天&#xff0c;各行各业都急需找到与顾客连接的新方式。为了满足这一需求&#xff0c;很多店铺和企业都推出了预定类小程序&#xff0c;分享一款开源版预订类小程序源码&#xff0c;一站式解决方案&#xff0c;覆盖餐饮、旅游、美容、医疗、教育等多个行业…

《架构思维:从程序员到CTO》:通往顶级架构师之路

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

让我们把Domino变成SFTP服务器

大家好&#xff0c;才是真的好。 远程共享文件有很多办法&#xff0c;其中值得注意的是SFTP方式。SFTP即SSH文件传输协议&#xff0c;通过使用SSH传输层&#xff0c;SFTP可以通过Internet连接安全地访问和移动大量数据文件。 今天我们就介绍使用Domino中的HTTP OSGI方式来实现…

智慧监测IN!计讯物联筑牢高速滑坡预警“安全锁”

在现代社会&#xff0c;高速公路以其高速、便捷的特性&#xff0c;早已成为连接城市与地区之间的重要纽带&#xff0c;承载着日益增长的车流和人流。然而&#xff0c;随着车流量的激增&#xff0c;高速公路面临的运营压力和安全挑战也随之加大&#xff0c;其中滑坡风险尤为突出…

软考中级-软件设计师(十)网络与信息安全基础知识

一、网络概述 1.1计算机网络的概念 计算机网络的发展&#xff1a;具有通信功能的单机系统->具有通信功能的多机系统->以共享资源为目的的计算机网络->以局域网及因特网为支撑环境的分布式计算机系统 计算机网络的功能&#xff1a;数据通信、资源共享、负载均衡、高…

Echarts柱状图横坐标不显示

本人遇到的问题&#xff1a;折线图横坐标可以正常显示 柱状图接收一样的数据在横坐标却显示不了 1.在前端打印是否能够正常接收数据、数据类型是否有误以及数据是否有内容 console.log(typeof optionbar.xAxis.data)console.log(optionbar.xAxis.data) 2.如上确定能够接收到数…

ue引擎游戏开发笔记(32)——为游戏添加新武器装备

1.需求分析&#xff1a; 游戏中角色不会只有一种武器&#xff0c;不同武器需要不同模型&#xff0c;甚至可能需要角色持握武器的不同位置&#xff0c;因此需要添加专门的武器类&#xff0c;方便武器后续更新&#xff0c;建立一个武器类。 2.操作实现&#xff1a; 1.在ue5中新建…

艺术的新领域——探索元宇宙艺术展带来的沉浸式艺术体验

在数字化的浪潮中&#xff0c;元宇宙艺术展成为了一种全新的展览形式&#xff0c;它通过虚拟现实、3D建模技术和互动平台&#xff0c;将传统艺术与现代科技巧妙结合&#xff0c;提供了一种前所未有的艺术欣赏方式。此类展览不仅展示了艺术作品的新颖呈现&#xff0c;还为参观者…

翻译《The Old New Thing》 - Understanding the consequences of WAIT_ABANDONED

Understanding the consequences of WAIT_ABANDONED - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20050912-14/?p34253 Raymond Chen 2005年09月12日 理解 WAIT_ABANDONED 的后果 简要 文章讨论了在多线程同步中&#xff0c;如果一个线程…

【贪心算法】最小生成树Kruskal算法Python实现

文章目录 [toc]问题描述最小生成树的性质证明 Kruskal算法Python实现时间复杂性 问题描述 设 G ( V , E ) G (V , E) G(V,E)是无向连通带权图&#xff0c; E E E中每条边 ( v , w ) (v , w) (v,w)的权为 c [ v ] [ w ] c[v][w] c[v][w]如果 G G G的一个子图 G ′ G^{} G′是…