15. 第十五章 类和对象

news2024/11/25 15:08:10

15. 类和对象

到现在你已经知道如何使用函数组织代码, 以及如何使用内置类型来组织数据.
下一步将学习'面向对象编程', 面向对象编程使用自定义的类型同时组织代码和数据.
面向对象编程是一个很大的话题, 需要好几章来讨论.
本章的代码示例可以从↓下载,
https://github.com/AllenDowney/ThinkPython2/blob/master/code/Point1.py 
练习的解答可以在↓下载.
https://github.com/AllenDowney/ThinkPython2/blob/master/code/Point1_soln.py
15.1 用户定义类型
我们已经使用了很多Python的内置类型; 现在我们要定义一个新类型.
作为示例, 我们将会新建一个类型Point, 用来表示二维空间中的一个点.
在数学的表示法中, 点通常使用括号中逗号分割两个坐标表示.
例如, (0, 0)表示原点, (x, y)表示一个在圆点右侧x单位, 上方y单位的点.

在Python中, 有好几种方法可以表达点.
* 我们可以将两个坐标分别保存到变量x和y中.
* 我们可以将坐标作为列表或元组的元素存储.
* 我们可以新建一个类型用对象表达点.

新建一个类型比其他方法更复杂一些, 但它的优点很快就显现出来.
用户定义的类型也称为'类'(class). 类的定义如下:
class Point:
	""" Represents a point in 2-D space. """

定义头表示新的类名为Point. 定义体是一个文档字符串, 解释这个类的用途.
可以在类定义中定义变量和函数, 我们会后面回到这个话题.
定义一个叫作Point的类会创建一个'对象类'(object class).
>>> Point
<class '__main__.Point'>

因为Point是在程序顶层定义的, 它的'全名'是__main__.Point.
类对象项一个创建对象的工厂. 要新建一个Point对象, 可以把Point当作函数类调研:
>>> blank = Point()
>>> blank
<__main__.Point object at 0x00000230EBFBB490>

返回值是一个Point对象的引用, 它们将它赋值给变量blank.
新建一个对象的过程称为'实例化'(instantiation), 而对象是这个类的一个实例.

在打印一个实例时, Python会告诉你它所属的类型,
以及存在内存中的位置(前缀0x表示后面的数字是十六进制的).

每个对象都是某个类的实例, 所以'对象''实例'这个两个词很多情况下都可以互换,
但是在本章中我们使用'实例'来表示一个自定义类型的对象.
15.2 属性
可以使用句点表示法给实例赋值:
>>> blank.x = 3.0
>>> blank.y = 4.0

这个语法和从模块中选择变量的语法类似, 如math.pi或者strings.whitespace.
但在种情况下, 我们是将值赋值给一个对象的有命名的元元素. 这些元素称为属性(attribute).
作为名词时, 'AT-trib-ute'发音的重音在第一个音节, 这与作为动词的'a-TRIB-ute'不同.

下面的图标展示了这些赋值的结果.
展示一个对象和其属性的状态图称为'对象图'(object diagram), 参见图15-1.

2023-04-14_00002

变量blank引用一个Point对象, 它包含了两个属性. 每个属性引用一个浮点数.
可以使用相同的语法来读取一个属性的值.
>>> blank.y
4.0
>>> x = blank.x
>>> x
3.0

表达式blank.x表示, '找打blank引用的对象, 并取得它的x属性的值'.
在这个例子中, 我们将那个值 赋值给一个变量x. 变量x和属性x并不冲突.
可以在任意表达式中使用句点表示法. 例如:
# %g用于打印浮点型数据时,会去掉多余的零,至多保留六位有效数字.
>>> '(%g, %g)' % (blank.x, blank.y)
'(3, 4)'
>>> import math
>>> distance = math.sqrt(blank.x ** 2 + blank.y ** 2)
>>> distance
5.0

可以将一个实例作为实参按通常的方式传递. 例如:
def print_point(p):
	print('(%g, %g)' % (p.x, p.y))
    
print_point接收一个点作为形参, 并按照属性表达式展示它.
可以传入blank作为实参来调用它:
>>> print_point(blank)
(3, 4)

在函数中, p是blank的一个别名, 所以如果函数修改了p, 则blank也会被修改.
作为练习, 编写一个叫作distance_between_points的函数, 
接收两个Point对象作为形参, 并返回它们之间的距离.
第一个坐标(x1=3, y1=4)
第二个坐标(x2=5, y2=6)
计算公式:(✓根号)
|AB| = (x1 - x2) ** 2 + (y1 - y2) ** 2
:
|AB| = (x1 - x2) ** 2 + (y1 - y2) ** 2 ** 0.5

import math


# 自定义对象
class Point:
    """自定义对象"""
    x = None
    y = None


# 实例两个对象
blank1 = Point()
blank1.x = 3.0
blank1.y = 4.0

blank2 = Point()
blank2.x = 5.0
blank2.y = 6.0


def distance_between_points(p1, p2):
    """
    计算两个Point对象之间的距离,
    :param p1: 第一个Point对象.
    :param p2: 第二个Point对象.
    :return: 两个Point对象之间的距离.
    """
    px = p1.x - p2.x
    py = p1.y - p2.y
    # return math.sqrt(px ** 2 + py ** 2)
    return ((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) ** 0.5


res = distance_between_points(blank1, blank2)
print(res)  # 2.8284271247461903

15.3 矩形
有时候对象因该有哪些属性非常明显, 但也有时候需要你来做决定,
例如, 假设你子啊设计一个表达矩形的类. 你会用什么属性来指定一个矩形的位置和尺寸呢?
可以忽视角度, 为了简单起见, 假定矩形不是垂直的就是水平的.
最少有以下两种可能.
* 可以指定一个矩形的一个角落(或者中心点), 宽度以及高度.
* 可以指定两个相对的角落.
现在还很难说哪一种方案更好, 所以作为示例, 我们仅限实现第一个.
class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner.
    """
    
文档字符列出了属性: width和height是数字, 用来指定左下角的顶点.
要表达一个矩形, 需要实例化一个Rectangle对象, 并对其属性赋值:
box = Rectangle()
# 设置宽
box.width = 100.0
# 设置高
box.height = 200.0
# 坐标对象 (0, 0)
box.corner = Ponint()
box.corner.x = 0.0
box.corner.y = 0.0

表达式box.corner.x表示, '去往box引用的对象, 并选择属性corner; 接着去往过那个对象, 并选择属性x'.
15-2展示了这个对象的状态. 作为另一个对象的属性存在的对象是'内嵌'.

2023-04-15_00001

15.4 作为返回值得示例
函数可以返回实例. 
例如, find_center接收一个Rectangle对象作为参数, 并返回一个Point对象,
包含这个Rectangle的中心点的坐标:
# 计算矩形的中心点.
def find_center(rect):
	p = Point()
	p.x = rect.corner.x + rect.width / 2
	p.y = rect.corner.y + rect.height / 2
	return p
	
下面是一个示例, 传入box作为实参, 并将结果的point对象赋值给center:
>>> center = find_center(box)
>>> print_point(center)
(50, 100)

# 完整代码

def print_point(p):
    print('(%g, %g)' % (p.x, p.y))


# 中心点
def find_center(rect):
    p = Point()
    p.x = rect.corner.x + rect.width / 2
    p.y = rect.corner.y + rect.height / 2
    # 实例作为返回值
    return p


class Point:
    """ Represents a point in 2-D space. """


class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner.
    """


if __name__ == '__main__':
    box = Rectangle()
    box.width = 100.0
    box.height = 200.0
    # 设置坐标
    box.corner = Point()
    box.corner.x = 0.0
    box.corner.y = 0.0
    
    center = find_center(box)
    print_point(center)  # (50, 100)

15.5 对象是可变的
可以通过一个对象的某个属性赋值来修改它的状态.
例如, 要修改一个矩形的尺寸而保持它的位置不变(左下角坐标为0, 0不变.),
可以修改属性width和height的值:
box.width = box.width + 50
box.height = box.width.height + 100

也可以编写函数来修改对象.
例如, grow_rectangle接收一个Rectangle对象和两个数, dwidth, dheight,
并把这些数加到矩形的宽度和高度上:
def grow_revtangle(rect, dwidth, dheight):
	rect.width += dwight
	rect.height += dheight
	
下面是展示这个函数效果的实例:
>>> box.width, box.height
(150.0, 300.0)
>>> grow_rectangle(box, 50, 100)
>>> box.width, box.height
(200.0, 400.0)

在函数中, rect是box的别名, 所以如果当修改了revt时, box也改变.

作为练习, 编写一个名为move_rectangle的函数, 接收一个Rectangle对象和两个分别名为dx和dy的数值.
它应当通过将dx添加到corner的x坐标和将dy添加到corner的y坐标来改变矩形的位置.
# 打印坐标
def print_point(p):
    print('(%g, %g)' % (p.x, p.y))


# 中心点
def find_center(rect):
    p = Point()
    p.x = rect.corner.x + rect.width / 2
    p.y = rect.corner.y + rect.height / 2
    # 实例作为返回值
    return p


# 移动坐标
def move_rectangle(rect, dx, dy):
    rect.corner.x += dx
    rect.corner.y += dy


class Point:
    """ Represents a point in 2-D space. """


class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner.
    """


if __name__ == '__main__':
    box = Rectangle()
    box.width = 100.0
    box.height = 200.0
    # 设置坐标
    box.corner = Point()
    box.corner.x = 0.0
    box.corner.y = 0.0
    # 打印坐标
    print_point(box.corner)  # (0, 0)
    # 移动坐标
    move_rectangle(box, 100, 100)
    print_point(box.corner)  # (100, 100)

15.6 复制
别名的使用有时候会让程序更难阅读, 因为一个地方的修改可能会给其他地方带来意想不到的变化.
要跟踪掌握所有引用到一个给定对象的变量非常困难.
使用别名的常用替代方案是复制对象. copy模块里有一个函数copy可以复制任何对象:
>>> p1 = Point()
>>> p1.x = 3.0
>>> p1.y = 4.0
>>> import copy
>>> p2 = copy.copy(p1)

p1和p2包含相同的数据, 但是它们不是同一个Point对象.
>>> print_point(p1)
(3, 4)
>>> print_point(p2)
(3, 4)
>>> p1 is p2
False
>>> p1 == p2
False

正如我们预料, is操作符告诉我们p1和p2不是同一个对象.
但你可能会预料==能得到True值, 因为这两个点(坐标点)包含相同的数据.
如果那样, 你会失望地发现对于实例来说, ==操作符的默认行为和is操作符相同,
它会检查对象同一性, 而不是对象相等性.
这是因为对于用户自定义类型, Python并不知道怎么才算相等. 至少现在还不行.


对象同一性(object identity): 当两个引用类型的变量存储的地址相同时, 它们引用的是同一个对象.
在Python中, ==操作符的默认行为是检查两个对象的值是否相等.
而is操作符则检查两个对象是否是同一个对象,即它们是否具有相同的内存地址。

对于内置类型(例如整数、浮点数、字符串等)Python已经定义了如何判断相等性.
但对于自定义类型, Python不会自动判断相等性, 因为它不知道如何判断两个对象是否相等.
因此, 如果你定义了自己的类, 你需要自己定义__eq__()方法来定义该类的相等性行为.
在这种情况下, ==操作符将使用您定义的__eq__()方法进行比较.

需要注意的是, 即使您定义了__eq__()方法, 使用is操作符也不会调用该方法,
因为is操作符只检查两个对象是否具有相同的内存地址.
如果使用copy.copy复制一个Rectangle, 你会发现它复制了Rectangle对象但并不复制内嵌的Point对象:
>>> box2 = copy.copy(box)
>>> box2 is box
False
# corner引用内嵌对象
>>> box2.corner is box.corner
True

15-3展示了这个操作的对象图.
这个操作成为浅复制(shallow copy), 因为它复制对象及其包含的任何引用, 但不复制内嵌对象.
(复制了内嵌对象的引用, 两个Recrangle对象的corner属性共用一个内嵌对象的引用,
哪个Recrangle对象对内嵌对象做了改动都会影响另一个Recrangle对象.)

2023-04-15_00005

对大多数应用, 这并不是你所想要的.
在这个例子里, 对一个Recrangle对象调用grow_rectangle并不影响其他对象,
当对任何Recrangle对象调用move_rectangle都会影响全部两个对象!
这种行为即混乱不清, 又容易导致错误.
幸好, copy模块还提供了一个名为deepcopy的方法, 它不但赋值对象, 还会复制对象中引用的对象,
甚至它们引用的对象, 以此类推.
所以你并不会惊讶这个操作为何称为深复制(deep copy).
>>> box3 = copy.deepcopy(box)
>>> box3 is box
False
>>> box3.corner is box.corner
False

box3个box是两个完全分开的对象.
作为练习, 编写move_rectangle的另一个版本, 它会新建并返回一个Rectangle对象, 而不是直接修改旧对象.
import copy


# 打印坐标
def print_point(p):
    print('(%g, %g)' % (p.x, p.y))


# 中心点
def find_center(rect):
    p = Point()
    p.x = rect.corner.x + rect.width / 2
    p.y = rect.corner.y + rect.height / 2
    # 实例作为返回值
    return p


# 移动坐标
def move_rectangle(rect, dx, dy):
    # 深复制一个Rectangle对象
    box2 = copy.deepcopy(rect)
    box2.corner.x += dx
    box2.corner.y += dy

    return box2


class Point:
    """ Represents a point in 2-D space. """


class Rectangle:
    """Represents a rectangle.
    attributes: width, height, corner.
    """


if __name__ == '__main__':
    box = Rectangle()
    box.width = 100.0
    box.height = 200.0
    # 设置坐标
    box.corner = Point()
    box.corner.x = 0.0
    box.corner.y = 0.0

    # 深复制一个矩形对象, 移动新矩形对象的坐标, 并返回新的矩形对象.
    box2 = move_rectangle(box, 100, 100)
    print_point(box2.corner)  # (100, 100)
    # 旧矩形对象不变
    print_point(box.corner)  # (0, 0)

15.7 调试
开始操作对象时, 可能会遇到一些新的异常.
如果试图访问一个并不存在的属性, 会得到AttrbuteErroe:
>>> p = Point()
>>> p.x = 3
>>> p.y = 4
>>> p.z

# 新版本
AttributeError: 'Point' object has no attribute 'z'
属性错误: 'Point'对象没有属性'z'

# 老版本
AttributeError: Point instance has no attribute 'z'
属性错误: 'Point'实例没有属性“z”
如果不清楚一个对象是什么类型, 可以问:
>>> type(p)
<class '__main__.Point'>

# 2.7版本, 显示 instance实例
<type 'instance'>
如果不确定一个对象是否拥有某个特定的属性, 可以使用内置函数hasatter:
>>> hasattr(p, 'x')
True
>>> hasattr(p, 'z')
False

第一个情形可以是任何对象, 第二个形参是一个包含属性名称的字符串.
也可以使用try语句来尝试对象是否拥有你需要的属性:
try:
	x = p.x
except AttributeEeeor:
	X = 0
	
这种方法可以使编写适用于不同类型的函数更加容易. 
关于这一主题的更多内容参见17.9.
15.8 术语表
(class): 一个用户定义的类型. 类定义会新建一个类对象.

类对象(class object): 一个包含用户定义类的信息的对象. 类对象可以用来创建改类型的实例.

实例(instance): 属于某个类的一个对象.

属性(sttribute): 一个对象中关联的有命名的值.

内嵌对象(embedded object): 作为一个对象的属性存储的对象.

浅复制(shallow copy): 复制对象的内容, 包括内嵌对象的引用; copy模块中的copy函数实现了这个功能.

深复制(deep copy): 复制对象的内容, 也包括内嵌对象, 以及它们内嵌的对象, 依次类推;
	copy模块中的deepcopy函数实现了这个功能.

对象图(object diagram): 一个展示对象, 对象的属性以及属性的值的图.
15.9 练习
1. 练习1
定义一个新的名为Circle的类表示圆形, 它的属性有center和radius, 
其中center(中心坐标)是一个Point对象, 而radius(半径)是一个数.

实例化一个Circle对象来代表一个圆心在(150, 100), 半径为75的圆形.

编写一个函数point_in_circle, 接收一个Circle对象和一个Point对象, 
并当Point处于Circle的边界或其内时返回True.

编写一个函数cert_in_circle, 接收一个Circle对象和一个Rectangle对象, 
并在Rectangle的任何一个角落在Circle之内是返回True.

另外, 还有一个更难的版本, 需要在Rectangle的任何部分都落在圆圈之内时返回True.

解答: https://github.com/AllenDowney/ThinkPython2/blob/master/code/Circle.py
如何判断一个坐标是否在圆内:
1. 圆心到这个点的距离小于圆的半径, 则这个点在圆内.
2. 圆心到这个点的距离等于圆的半径, 则这个点在圆周上.
3. 圆心到这个点的距离大于圆的半径, 则这个点在圆外.


计算两个坐标的距离:
|AB| = (x1 - x2) ** 2 + (y1 - y2) ** 2 ** 0.5
# 自定义对象
class Point:
    """坐标"""
    x = None
    y = None


class Circle:
    """圆"""


class Rectangle:
    """矩形"""


def distance_between_points(p1, p2):
    """
    计算两个Point对象之间的距离,
    :param p1: 第一个Point对象.
    :param p2: 第二个Point对象.
    :return: 两个Point对象之间的距离.
    """
    return ((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) ** 0.5


def point_in_circle(cir, p):
    # 计算两个坐标之间的距离.
    distance = distance_between_points(cir.center, p)
    # 距离是否在圆的半径内
    print('输入的坐标离圆的距离为:%d,' % distance, end='\t')
    if distance <= cir.radius:
        return True


def cert_in_circle(cir, rect):
    # 计算矩形的四个角的坐标离圆心坐标的距离
    # 左下角就是矩形的坐标
    bottom_left = rect.corner
    # 左上角, y + height
    upper_left = Point()
    upper_left.x = rect.width
    upper_left.y = bottom_left.y + rect.height
    # 右下角 x + width
    bottom_right = Point()
    bottom_right.y = rect.height
    bottom_right.x = bottom_left.x + rect.width

    # 右上角
    top_right = Point()
    # x = 左上角加width
    top_right.x = upper_left.x + rect.width
    top_right.y = upper_left.y

    # 计算四个角的是否在圆内
    corner_list = [('左下角', bottom_left), ('左上角', upper_left),
                   ('右下角', bottom_right), ('右上角', top_right)]

    count = 0
    for corner_name, corner_point in corner_list:
        distance = distance_between_points(cir.center, corner_point)
        print('矩形的%s离圆心的距离为: %d.' % (corner_name, distance), end=' ')

        if distance <= cir.radius:
            count += 1
            print('矩形这个角在圆内!')
        else:
            print('矩形这个角不在圆内!')

    if count == 4:
        print('圆的任何部分都在圆内')


def main(p2_obj):
    # 实例化对象得到一个圆
    round1 = Circle()
    # 设置圆的坐标150.0
    round1.center = Point()
    round1.center.x = 150
    round1.center.y = 100
    # 设置圆的半径75
    round1.radius = 75

    # 判断坐标是否在圆内.
    is_inside_circle = point_in_circle(round1, p2_obj)
    if is_inside_circle:
        print('坐标在圆内!')
    else:
        print('坐标不在圆内!')

    # 输入的矩形的任何一个角是否在圆内
    # 实例化一个矩形对象
    rect = Rectangle()
    rect.width = 100
    rect.height = 200
    rect.corner = p2

    cert_in_circle(round1, rect)


if __name__ == '__main__':
    p2 = Point
    p2.x = 300
    p2.y = 300
    main(p2)

2023-04-16_00002

2. 练习2
编写一个名为draw_rect的函数, 接收一个Turtle对象, 和一个Rectangle对象组我形参,
并使用Turtle来绘制这个Rectangle. 如何使用Turtle对象的示例参见第4.

编写一个draw_cect的函数, 接收一个Turtle对象和一个Circle对象, 并绘制出Circle.
解答: https://github.com/AllenDowney/ThinkPython2/blob/master/code/polygon.py
import turtle

from Point1 import Point, Rectangle
# polygon.py 文件以及写的练习文件.
import polygon


class Circle:
    """"""


def draw_circle(t, circle):

    t.pu()
    t.goto(circle.center.x, circle.center.y)
    t.fd(circle.radius)
    t.lt(90)
    t.pd()
    polygon.circle(t, circle.radius)


def draw_rect(t, rect):
    t.pu()
    t.goto(rect.corner.x, rect.corner.y)
    t.setheading(0)
    t.pd()

    for length in rect.width, rect.height, rect.width, rect.height:
        t.fd(length)
        t.rt(90)


if __name__ == '__main__':
    bob = turtle.Turtle()

    length = 400
    bob.fd(length)
    bob.bk(length)
    bob.lt(90)
    bob.fd(length)
    bob.bk(length)

    box = Rectangle()
    box.width = 100.0
    box.height = 200.0
    box.corner = Point()
    box.corner.x = 50.0
    box.corner.y = 50.0

    draw_rect(bob, box)

    circle = Circle
    circle.center = Point()
    circle.center.x = 150.0
    circle.center.y = 100.0
    circle.radius = 75.0

    draw_circle(bob, circle)

    turtle.mainloop()

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

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

相关文章

Linux 并发与竞争实验学习

Linux 并发与竞争实验学习 原子操作实验 这里原子操作就是采用原子变量来保护一个程序运行的完整过程&#xff0c;使用atomic 来实现一次只能允许一个应用访问 LED&#xff0c;创建atomic.c文件&#xff0c;其实改动内容就是添加原子变量&#xff0c; 要在设备结构体数据添加…

MEMS:Lecture 19 Wafer bonding package

讲义 Current MEMS Packages Die Level (芯片级) 封装 图片描述&#xff1a;左侧的图显示了Cronos继电器的芯片级封装。这种封装方式是在晶圆切割后&#xff0c;将独立的MEMS芯片组装到单独的陶瓷封装中。特点&#xff1a; Die level release and ceramic package&#xff1a…

数据库管理-第204期 数据库的IO掉速,也许是SSD的锅(20240615)

数据库管理204期 2024-06-15 数据库管理-第204期 数据库的IO掉速&#xff0c;也许是SSD的锅&#xff08;20240615&#xff09;1 SSD物理结构2 SSD颗粒类型3 DRAM & SLC Cache3.1 DRAM3.2 SLC Cache3.3 其他方式 4 缓外降速总结 数据库管理-第204期 数据库的IO掉速&#xff…

C++ Windows下Glog日志库安装使用教程

🙋 介绍:glog是google推出的一款轻量级c++开源日志框架。  环境配置:windows+VS2015+gflags 2.2.2+glog-0.3.5。为避免新版本(glog V0.7.1)踏坑,建议装低版本,这里我选用的是V0.3.5。 1. 下载 在gflags官方中下载gflags代码,官方地址 在Glog官方中下载,githut地址:…

探索开源世界:2024年值得关注的热门开源项目推荐

文章目录 每日一句正能量前言GitCode成立背景如何使用GitCode如何把你现有的项目迁移至 GitCode&#xff1f;热门开源项目推荐actions-poetry - 管理 Python 依赖项的 GitLab CI/CD 工具项目概述技术分析应用场景特点项目地址 Spider - 网络爬虫框架项目简介技术分析应用场景项…

【Mac】Luminar Neo for mac(图像编辑软件)软件介绍及同类型软件比较

Luminar Neo软件介绍 Luminar Neo 是一款由 Skylum 开发的功能强大的照片编辑软件&#xff0c;专为摄影师和摄影爱好者设计。它适用于 Mac 和 Windows 平台&#xff0c;提供了一系列先进的编辑工具和功能&#xff0c;使用户能够轻松提升和优化他们的照片。以下是 Luminar Neo …

C#开发-集合使用和技巧(四)集合中常用的查询方法

集合中常用的查询方法 测试数据准备&#xff1a;查询方法详解**Where**条件查询定义和注释&#xff1a;功能详细说明&#xff1a;应用实例查找所有设备类型为“生产设备”的对象 结果测试&#xff1a;查询所有测试结果大于90的设备多条件查询&#xff1a;类型为生产设备同时测试…

2023年的Top20 AI应用在近一年表现怎么样?

AI应用现在进入寒武纪大爆发时代&#xff0c;百花争艳。如果倒回到2023年初&#xff0c;那时候排名靠前的AI应用在一年多时间&#xff0c;发生了哪些变化&#xff1f;能带给我们什么启示&#xff1f; 在2023年1月&#xff0c;排名靠前20的AI应用是&#xff1a; DeepL&#xff…

datax图形化界面datax-web安装及使用

环境准备&#xff1a;需要先安装git和maven git安装可参考git的安装-CSDN博客 maven只需解压安装包&#xff0c;配置环境变量即可使用 1 源代码下载 直接从Git上面获得datax-web源代码 git clone https://gitee.com/WeiYe-Jing/datax-web.git 2 打包项目 进入项目源码根…

Spring底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点.比如: beanClass:表示Bean类型scope:表示Bean作用域,单例/原型等lazyInit:表示Bean是否懒加载initMethodName:表示Bean初始化时要执行的方法destoryMethodName:表示Bean销毁时…

用于每个平台的最佳WordPress LMS主题

你已选择在 WordPress 上构建学习管理系统 (LMS)了。恭喜&#xff01; 你甚至可能已经选择了要使用的 LMS 插件&#xff0c;这已经是成功的一半了。 现在是时候弄清楚哪个 WordPress LMS 主题要与你的插件配对。 我将解释 LMS 主题和插件之间的区别&#xff0c;以便你了解要…

Unity中实现ScrollRect 滚动定位到视口内

Demo链接: https://download.csdn.net/download/qq_41973169/89439428https://download.csdn.net/download/qq_41973169/89439428 一、前言 Unity版本:2020.1.x 如果需要资源请联系我我会分享给你 因为本人也要存储一下Demo所以上传到这里了但是又不能设置不需要积分 在Un…

车载网络安全指南 软件层面开发阶段(八)

返回总目录->返回总目录<- 目录 前言 一、软件层面产品开发启动 二、确定网络安全需求 三、软件架构设计 四、软件层面漏洞分析 五、软件单元设计和实现 六、软件实现的分析与评估 七、软件单元测试 八、软件集成和测试 九、网络安全验证 十、细化网络安全评估…

发布自己的c#包到nuget

1)创建自己的nuget账号 NuGet Gallery | Home 2)在Rider中-->项目邮件-->properties 注意&#xff1a;必须勾选生成nuget包 3)编译后&#xff0c;将生成一个包 4)点击上传包 5)将之前的nuget包拖拽过来&#xff0c;点击上传即可&#xff0c;如果有不对的比如&#xf…

C++ 43 之 自增运算符的重载

#include <iostream> #include <string> using namespace std;class MyInt{friend ostream& operator<< (ostream& cout , MyInt& int1); public:MyInt(){this->m_num 0;}// 前置自增&#xff1a; 成员函数实现运算符的重载 返回的是 引用&a…

Android 蓝牙配对Settings应用里面的简要流程记录

Android 蓝牙配对Settings应用里面的简要流程记录 文章目录 Android 蓝牙配对Settings应用里面的简要流程记录一、前言二、Settings蓝牙配对的关键代码1、接收蓝牙请求的地方 AndroidManifest.xml2、BluetoothPairingRequest3、BluetoothPairingService4、BluetoothPairingDial…

石头、剪子、布小游戏图形化

石头、剪子、布小游戏图形化 也是之前编写了一个石头、剪子、布的小游戏&#xff0c;总感觉界面不够友好&#xff0c;AI时代到来&#xff0c;一切都无所不能&#xff0c;而且编程效率大大提高了。所以用AI大模型进行程序代码重构&#xff0c;再稍加修改&#xff0c;效果还不错…

LLM proj - 审稿大模型

常用数据处理 主要是四种方式&#xff1a;正则表达式、AC自动机、困惑度过滤低质文本、最小哈希算法实现文本去重 1. 正则表达式&#xff0c;去做一些模式匹配 ex&#xff1a; # 论文的评审内容有时会存在大量列举reference&#xff08;参考文献&#xff09;的情况 # 这些r…

KKT基础知识

KKT条件定义 KKT条件(Karush–Kuhn–Tucker conditions)是最优化&#xff08;特别是非线性规划&#xff09;领域最重要的成果之一&#xff0c;是判断某点是极值点的必要条件。 最优化问题 要选择一组参数&#xff08;变量&#xff09;&#xff0c;在满足一定的限制条件&…

Unity动态添加聊天文本

1.创建一个滚动视图 2.调整滚动视图的位置并删掉这个 3.创建一个输入框和一个按钮 这里插一句一定要给content添加这个组件并设置单元格大小 4创建一个脚本并编写下面代码 using System.Collections; using System.Collections.Generic; using TMPro; using Unity.VisualScrip…