Python中的魔法函数

        大家好,Python作为一种高级编程语言,以其简洁、优雅和易读性而闻名。然而,Python的强大之处不仅仅在于其语法的简洁性,还在于其灵活的面向对象编程范式。在Python中,有一类特殊的方法被称为“魔法函数”,它们以双下划线(__)开头和结尾,为Python提供了一种强大的机制,使得用户能够定制类的行为,使其更加符合特定的需求和使用场景。

一、介绍

1、什么是Python魔法函数?

        在Python中,魔法函数是一类特殊的方法,它们以双下划线(__)开头和结尾,在特定情况下由Python解释器自动调用。这些方法被称为“魔法”,因为它们能够在不显式调用的情况下,在类定义中执行特定的操作。由于它们对于Python对象的行为具有隐式的影响,因此被称为“魔法”。

        魔法函数的存在使得Python类能够像内置数据类型一样进行操作,使得代码更加简洁、灵活,并且易于理解。通过合理地使用魔法函数,可以使得自定义的类更加符合Python的惯例和语言规范,同时提高代码的可读性和可维护性。

2、魔法函数的重要性

        Python魔法函数在编写面向对象的代码时至关重要。它们提供了一种简洁、优雅的方式来定制类的行为,使得用户能够更加灵活地使用和扩展已有的类。通过合理地使用魔法函数,用户可以使得自定义的类更加符合Python的惯例和语言规范,同时提高代码的可读性和可维护性。

3、简单示例说明魔法函数是如何工作的

        让我们通过一个简单的示例来说明魔法函数是如何工作的。假设我们有一个名为Point的类,用于表示二维平面上的点,并且我们想要定义一个魔法函数来计算两个点之间的距离。

import math

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"({self.x}, {self.y})"
    
    def distance_to(self, other_point):
        return math.sqrt((self.x - other_point.x)**2 + (self.y - other_point.y)**2)

# 创建两个点对象
p1 = Point(0, 0)
p2 = Point(3, 4)

# 输出点的字符串表示
print("Point 1:", p1)  # 输出:Point 1: (0, 0)
print("Point 2:", p2)  # 输出:Point 2: (3, 4)

# 计算两点之间的距离
distance = p1.distance_to(p2)
print("Distance between points:", distance)  # 输出:Distance between points: 5.0

        在上面的示例中,我们定义了一个Point类,并实现了__init____str__distance_to等方法。其中,__init__方法用于初始化对象,__str__方法用于返回对象的字符串表示,distance_to方法用于计算两个点之间的距离。

        当我们使用print()函数输出点对象时,Python解释器会自动调用__str__方法来获取对象的字符串表示。而当我们调用p1.distance_to(p2)时,Python解释器会自动调用distance_to方法来计算两个点之间的距离。这些魔法函数的存在使得我们能够以一种更加直观和自然的方式操作对象,从而使得代码更加清晰和易于理解。

二、常用的魔法函数及其作用

下面将介绍一些常见的魔法函数以及对应的示例:

1、__init__(self, ...)

初始化对象。

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

obj = MyClass(10)

2、__str__(self)

返回对象的字符串表示。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __str__(self):
        return f"MyClass with value: {self.value}"

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

3、__repr__(self)

返回对象的“官方”字符串表示,通常用于调试。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __repr__(self):
        return f"MyClass({self.value})"

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

4、__len__(self)

返回对象的长度。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __len__(self):
        return len(self.items)

my_list = MyList([1, 2, 3, 4])
print(len(my_list))  # 输出: 4

5、__getitem__(self, key)

获取对象的某个元素。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __getitem__(self, index):
        return self.items[index]

my_list = MyList([1, 2, 3, 4])
print(my_list[2])  # 输出: 3

6、__setitem__(self, key, value)

设置对象的某个元素。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __setitem__(self, index, value):
        self.items[index] = value

my_list = MyList([1, 2, 3, 4])
my_list[2] = 10
print(my_list.items)  # 输出: [1, 2, 10, 4]

7、__delitem__(self, key)

删除对象的某个元素。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __delitem__(self, index):
        del self.items[index]

my_list = MyList([1, 2, 3, 4])
del my_list[2]
print(my_list.items)  # 输出: [1, 2, 4]

8、__contains__(self, item)

判断对象是否包含某个元素。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __contains__(self, item):
        return item in self.items

my_list = MyList([1, 2, 3, 4])
print(2 in my_list)  # 输出: True

9、__iter__(self)

返回迭代器对象,用于支持对象的迭代。

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __iter__(self):
        return iter(self.items)

my_list = MyList([1, 2, 3, 4])
for item in my_list:
    print(item)  # 输出: 1 2 3 4

10、__next__(self)

迭代器的下一个元素。

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        result = self.data[self.index]
        self.index += 1
        return result

my_iterator = MyIterator([1, 2, 3, 4])
for item in my_iterator:
    print(item)  # 输出: 1 2 3 4

11、__call__(self, ...)

使对象可以像函数一样被调用。

class MyCallable:
    def __call__(self, x, y):
        return x + y

add = MyCallable()
print(add(3, 5))  # 输出: 8

12、__add__(self, other)

实现对象的加法。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __add__(self, other):
        return self.value + other

obj = MyClass(10)
result = obj + 5
print(result)  # 输出: 15

13、__sub__(self, other)

实现对象的减法。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __sub__(self, other):
        return self.value - other

obj = MyClass(10)
result = obj - 3
print(result)  # 输出: 7

14、__mul__(self, other)

实现对象的乘法。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __mul__(self, other):
        return self.value * other

obj = MyClass(10)
result = obj * 2
print(result)  # 输出: 20

15、__truediv__(self, other)

实现对象的真除法。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __truediv__(self, other):
        return self.value / other

obj = MyClass(10)
result = obj / 2
print(result)  # 输出: 5.0

16、__floordiv__(self, other)

实现对象的整除法。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __floordiv__(self, other):
        return self.value // other

obj = MyClass(10)
result = obj // 3
print(result)  # 输出: 3

17、__mod__(self, other)

实现对象的取模运算。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __mod__(self, other):
        return self.value % other

obj = MyClass(10)
result = obj % 3
print(result)  # 输出: 1

18、__pow__(self, other[, modulo])

实现对象的幂运算。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __pow__(self, other, modulo=None):
        return self.value ** other

obj = MyClass(2)
result = obj ** 3
print(result)  # 输出: 8

19、__eq__(self, other)

实现对象的等于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __eq__(self, other):
        return self.value == other

obj = MyClass(10)
result = obj == 10
print(result)  # 输出: True

20、__ne__(self, other)

实现对象的不等于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __ne__(self, other):
        return self.value != other

obj = MyClass(10)
result = obj != 5
print(result)  # 输出: True

21、__lt__(self, other)

实现对象的小于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __lt__(self, other):
        return self.value < other

obj = MyClass(10)
result = obj < 15
print(result)  # 输出: True

22、__le__(self, other)

实现对象的小于等于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __le__(self, other):
        return self.value <= other

obj = MyClass(10)
result = obj <= 10
print(result)  # 输出: True

23、__gt__(self, other)

实现对象的大于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __gt__(self, other):
        return self.value > other

obj = MyClass(10)
result = obj > 5
print(result)  # 输出: True

24、__ge__(self, other)

实现对象的大于等于比较。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __ge__(self, other):
        return self.value >= other

obj = MyClass(10)
result = obj >= 10
print(result)  # 输出: True

25、__hash__(self)

返回对象的哈希值,用于支持对象在字典等哈希表数据结构中的使用。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __hash__(self):
        return hash(self.value)

obj = MyClass(10)
print(hash(obj))  # 输出: 10

26、__bool__(self)

返回对象的布尔值,用于控制对象在布尔上下文中的行为。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __bool__(self):
        return self.value > 0

obj1 = MyClass(10)
obj2 = MyClass(0)
print(bool(obj1))  # 输出: True
print(bool(obj2))  # 输出: False

27、__getattr__(self, name)

获取对象的属性,当属性不存在时被调用。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __getattr__(self, name):
        return f"Attribute {name} not found"

obj = MyClass(10)
print(obj.foo)  # 输出: Attribute foo not found

28、__setattr__(self, name, value)

设置对象的属性。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __setattr__(self, name, value):
        print(f"Setting attribute {name} to {value}")
        super().__setattr__(name, value)

obj = MyClass(10)
obj.foo = 'bar'  # 输出: Setting attribute foo to bar

29、__delattr__(self, name)

删除对象的属性。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __delattr__(self, name):
        print(f"Deleting attribute {name}")
        super().__delattr__(name)

obj = MyClass(10)
del obj.value  # 输出: Deleting attribute value

30、__dir__(self)

返回对象的属性列表。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __dir__(self):
        return ['value']

obj = MyClass(10)
print(dir(obj))  # 输出: ['value']

31、__enter__(self)

进入上下文管理器时调用的方法,通常与 with 语句一起使用。

class MyResource:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting the context")

with MyResource() as res:
    print("Inside the context")
# 输出:
# Entering the context
# Inside the context
# Exiting the context

32、__exit__(self, exc_type, exc_value, traceback)

退出上下文管理器时调用的方法,通常与 with 语句一起使用。

class MyResource:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting the context")

with MyResource():
    print("Inside the context")
# 输出:
# Entering the context
# Inside the context
# Exiting the context

三、自定义魔法函数

        自定义魔法函数是通过在自定义类中定义特殊方法(以双下划线开头和结尾的方法)来实现的。这些魔法方法允许自定义类模拟内置类型的行为,例如算术运算、比较、字符串表示等。

下面是如何在自定义类中定义和使用自定义的魔法函数的详细介绍:

  1. 选择合适的魔法函数:首先,确定你想要模拟的内置类型行为,并选择适合的魔法函数。例如,如果你想要支持对象的加法运算,你可以实现 __add__ 方法。

  2. 在类中定义魔法函数:在自定义类中定义选定的魔法函数,并实现相应的逻辑。确保你的魔法函数接受适当数量的参数,并按照预期返回结果。

  3. 使用自定义的魔法函数:创建类的实例并使用定义的魔法函数来执行相应的操作。

下面是一个示例,展示如何在自定义类中实现自己的 __add____str__ 魔法函数:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        if isinstance(other, Point):
            # 如果 other 是 Point 类的实例,则执行向量加法
            return Point(self.x + other.x, self.y + other.y)
        elif isinstance(other, (int, float)):
            # 如果 other 是整数或浮点数,则执行标量加法
            return Point(self.x + other, self.y + other)
        else:
            # 其他情况下引发 TypeError
            raise TypeError("Unsupported operand type for +")

    def __str__(self):
        return f"({self.x}, {self.y})"

# 创建两个 Point 对象
p1 = Point(1, 2)
p2 = Point(3, 4)

# 使用 __add__ 进行向量加法
result_vector = p1 + p2
print("Vector Addition Result:", result_vector)  # 输出: Vector Addition Result: (4, 6)

# 使用 __add__ 进行标量加法
result_scalar = p1 + 5
print("Scalar Addition Result:", result_scalar)  # 输出: Scalar Addition Result: (6, 7)

        在上面的示例中,我们定义了一个 Point 类,并在该类中实现了 __add__ 方法来支持向量加法和标量加法。同时,我们还实现了 __str__ 方法来返回对象的字符串表示。最后,我们创建了两个 Point 对象并进行加法运算,演示了自定义魔法函数的使用。

四、魔法函数的应用

        魔法函数在实际编程中有许多应用场景,它们可以使代码更加简洁、清晰和易于维护。下面是一些常见的魔法函数的实际应用和示例:

1、迭代器和可迭代对象

        通过实现 __iter____next__ 方法,可以将一个类变成可迭代对象或迭代器,使其能够被 for 循环等语句使用。

class MyRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.start >= self.end:
            raise StopIteration
        current = self.start
        self.start += 1
        return current

# 使用自定义的迭代器
for num in MyRange(1, 5):
    print(num)  # 输出: 1 2 3 4

2、运算符重载

通过实现 __add____sub__ 等方法,可以使对象支持常见的算术运算,增强类的功能性。

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.x + other.x, self.y + other.y)
        else:
            raise TypeError("Unsupported operand type for +")

# 使用自定义的运算符重载
v1 = Vector(1, 2)
v2 = Vector(3, 4)
result = v1 + v2
print(result.x, result.y)  # 输出: 4 6

3、上下文管理器

        通过实现 __enter____exit__ 方法,可以创建上下文管理器,用于资源管理和异常处理等场景。

class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
    
    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file
    
    def __exit__(self, exc_type, exc_value, traceback):
        self.file.close()

# 使用自定义的上下文管理器
with FileManager('example.txt', 'w') as f:
    f.write('Hello, world!')

4、属性访问控制

通过实现 __getattr____setattr__ 等方法,可以控制对象属性的访问、设置和删除。

class ProtectedAttributes:
    def __init__(self):
        self._protected = 0
    
    def __getattr__(self, name):
        if name == 'protected':
            raise AttributeError("This attribute is protected")
        else:
            return super().__getattr__(name)
    
    def __setattr__(self, name, value):
        if name == 'protected':
            raise AttributeError("Cannot set protected attribute")
        else:
            super().__setattr__(name, value)

# 使用自定义的属性访问控制
obj = ProtectedAttributes()
obj.public = 1
print(obj.public)  # 输出: 1
obj.protected = 2  # 引发 AttributeError

        这些示例展示了魔法函数在实际编程中的应用,它们使得代码更加简洁、清晰和易于维护,同时也增强了类的功能性和灵活性。

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

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

相关文章

【并查集】专题练习

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 模板 836. 合并集合 - AcWing题库 #include<bits/stdc.h> using lllong long; //#define int ll const int N1e510,mod1e97; int n,m; int p[N],sz[N]; int find(int a) {if(p[a]!a) p[a]find(p[a]);return p[a…

C++_list简单源码剖析:list模拟实现

文章目录 &#x1f680;1. ListNode模板&#x1f680;2. List_iterator模板(重要)&#x1f331;2.1 List_iterator的构造函数&#x1f331;2.2 List_iterator的关于ListNode的行为 &#x1f680;3. Reverse_list_iterator模板(拓展)&#x1f680;4. List模板(核心)&#x1f331…

更换固件后飞控OSD叠显不对/叠显不显示/叠显乱码问题

笔者用的飞控型号为SpeedyBeeF405V4的飞控&#xff0c;OSD叠显芯片型号为AT7456E。 我的这款飞控是支持两款固件的&#xff0c;INAV和BetaFlight。 开始飞控的默认固件为BetaFlight&#xff0c;切换INAV固件后&#xff0c;进行OSD调整&#xff0c;但发现水平线无法正常显示&…

分享一个 ASP.NET Web Api 上传和读取 Excel的方案

前言 许多业务场景下需要处理和分析大量的数据&#xff0c;而 Excel 是业务人员常用的数据表格工具&#xff0c;因此&#xff0c;将 Excel 表格中内容上传并读取到网站&#xff0c;是一个很常见的功能&#xff0c;目前有许多成熟的开源或者商业的第三方库&#xff0c;比如 NPO…

ROS2在RVIZ2中加载机器人urdf模型

参考ROS2-rviz2显示模型 我这边用的solid works生成的urdf以及meshes&#xff0c;比参考的方法多了meshes 问题一&#xff1a;Error retrieving file [package://rm_dcr_description/meshes/leftarm_link7.STL]: Package [rm_dcr_description] does not exist 这个是urdf模型中…

蓝桥杯单片机第五届国赛题目

前言&#xff1a;针对串口的练手&#xff0c;此处只作代码记录&#xff0c;不进行分析和展示 目录 题目代码底层驱动主程序核心代码 题目 代码 注&#xff1a;EEPROM的五组后丢弃用一个记录次数的变量进行循环即可&#xff0c;我没有写这一部分代码。 底层驱动 IIC unsign…

【Linux】Linux环境基础开发工具_3

文章目录 四、Linux环境基础开发工具2. vim3. gcc和g动静态库的理解 未完待续 四、Linux环境基础开发工具 2. vim vim 怎么批量化注释呢&#xff1f;最简单的方法就是在注释开头和结尾输入 /* 或 */ 。当然也可以使用快捷键&#xff1a; Ctrl v 按 hjkl 光标移动进行区域选择…

用HAL库改写江科大的stm32入门-6-3 PWM驱动LED呼吸灯

接线图&#xff1a; 2 :实验目的&#xff1a; 利用pwm实现呼吸灯。 关键PWM定时器设置&#xff1a; 代码部分&#xff1a; int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*…

JVM 常见配置参数

JVM 配置常见参数 Java虚拟机的参数&#xff0c;在启动jar包的时候通过java 命令指定JVM参数 -options表示Java虚拟机的启动参数&#xff0c;class为带有main()函数的Java类&#xff0c;args表示传递给主函数main()的参数。 一、系统查看参数: -XX:PrintVMOptions可以在程序…

ADC数模转换器

一、ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 1、ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 2、12位逐次逼近型ADC&#xff0c;1us转换时间 3、输入电压范围&#xff1a;0~3.3V&a…

Visual Studio 2022创建dll并调用

需求&#xff1a; 创建A项目&#xff0c;有函数和类&#xff0c;将A项目生成DLL动态链接库 创建B项目&#xff0c;使用A项目生成的dll和lib相关文件 正常项目开发.h用于函数声明&#xff0c;.cpp用于函数实现&#xff0c;但是项目开发往往不喜欢将.cpp函数实现的代码发给别人&…

只出现一次的数字II ---- 位运算

题目链接 题目: 分析: 对于只出现一次的数字, 他的任意一个bit位, 可能是0或1对于其余出现3次的数字, 假设有3n个数, 那么他们的任意一个bit相加的和可能是3n个0或3n个1那么对于数组中的全部数字的任意一个bit位之和共有三种情况: 3n个1 1 3n13n个0 1 13n个1 0 3n3n个0…

反VC情绪:加密市场需要新的分布式代币发行方式

GME事件 GME事件反应了社交媒体在金融决策中的影响力&#xff0c;散户投资者群体通过集体行动&#xff0c;改变了很多人对股市的看法和参与方式。 GME事件中&#xff0c;meme扮演了核心角色。散户投资者使用各种meme来沟通策略、激励持股行为&#xff0c;创造了一种反对华尔街…

2.5Bump Mapping 凹凸映射

一、Bump Mapping 介绍 我们想要在屏幕上绘制物体的细节&#xff0c;从尺度上讲&#xff0c;一个物体的细节分为&#xff1a;宏观、中观、微观宏观尺度中其特征会覆盖多个像素&#xff0c;中观尺度只覆盖几个像素&#xff0c;微观尺度的特征就会小于一个像素宏观尺度是由顶点或…

为何懂行的人都在选海信Mini LED?

今年的618大促比往年来得要更早一些。纵览各电商平台的电视产品&#xff0c;能发现Mini LED电视的出镜率很高&#xff0c;成了各大品牌的主推产品。 对于什么样的Mini LED更值得买&#xff0c;各品牌都有自己的说辞。因为缺乏科学系统的选购标准&#xff0c;消费者容易在各方说…

【VSCode】快捷方式log去掉分号

文章目录 一、引入二、解决办法 一、引入 我们使用 log 快速生成的 console.log() 都是带分号的 但是我们的编程习惯都是不带分号&#xff0c;每次自动生成后还需要手动删掉分号&#xff0c;太麻烦了&#xff01; 那有没有办法能够生成的时候就不带分号呢&#xff1f;自然是有…

国产身份域控在接管计算机登录时,要考虑哪些场景?

当客户提出需要宁盾来接管计算机做统一认证时&#xff0c;我们知道&#xff0c;他要的其实有辣么多&#xff1a; 一、多操作系统的统一登录 信创项目中&#xff0c;客户的计算机操作系统存在windows、Linux以及麒麟、统信等国产操作系统混合使用的情况&#xff0c;而员工想要的…

云动态摘要 2024-05-31

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [1.5折起]年中盛惠--AI分会场 腾讯云 2024-05-30 人脸核身、语音识别、文字识别、数智人、腾讯混元等热门AI产品特惠&#xff0c;1.5折起 云服务器ECS试用产品续用 阿里云 2024-04-14 云…

Zynq学习笔记--AXI4-Stream 图像数据从仿真输出到图像文件

目录 1. 简介 2. 构建工程 2.1 Vivado 工程 2.2 TestBench 代码 2.3 关键代码分析 3. VPG Background Pattern ID (0x0020) Register 4. 总结 1. 简介 使用 SystemVerilog 将 AXI4-Stream 图像数据从仿真输出到图像文件 (PPM)。 用到的函数包括 $fopen、$fwrite 和 $f…

dmdts连接kingbase8报错

dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…