当前位置:   article > 正文

Python-VBA函数之旅-issubclass函数

Python-VBA函数之旅-issubclass函数

目录

一、issubclass函数的常见应用场景:

二、issubclass函数使用注意事项:

三、如何用好issubclass函数?

1、issubclass函数:

1-1、Python:

1-2、VBA:

2、推荐阅读:

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



一、issubclass函数的常见应用场景:

        issubclass函数Python编程中有多种实际应用场景,它主要用于在运行时检查类的继承关系,常见的应用场景有:

1、类型检查:在编写可重用和灵活的代码时,你可能需要编写能够处理多种类型的函数或方法;使用issubclass()函数,你可以检查传入的参数类型是否是期望类型的子类,从而根据类型执行不同的操作。

2、设计模式:在实现某些设计模式,如工厂模式或策略模式时,issubclass()函数可以帮助确定对象的具体类型,从而决定如何执行某些操作。

3、异常处理:在处理异常时,issubclass()函数可以用来检查捕获的异常是否是某个特定异常类的实例,这可以用来实现更加精细的错误处理逻辑。

4、反射:在编写需要动态检查类关系的代码时,如在编写测试框架或元编程工具时,issubclass()函数可以帮助你确定类之间的继承关系。

5、文档生成:当生成类或模块的文档时,你可能想要列出所有的子类,以便提供完整的类层次结构信息。

6、框架和库开发:在构建框架或库时,你可能会提供一个基类或接口,要求用户实现特定的方法;使用issubclass()函数,你可以确保用户提供的类确实实现了你期望的接口。

7、测试和调试:在编写单元测试和调试代码时,issubclass()函数可以用来验证类的结构是否符合预期,帮助开发者发现和修复问题。

8、元类编程:在更高级的编程场景中,如元编程,issubclass()函数可以用于在运行时构建和修改类的行为。

        总之,issubclass()函数在Python编程中提供了强大的类型检查能力,特别是在面向对象编程和构建可扩展系统的场景中非常有用。

二、issubclass函数使用注意事项:

        在Python中使用issubclass()函数时,需牢记以下几点:

1、参数类型:issubclass()函数的第一个参数必须是一个类对象,第二个参数可以是一个类对象或者是一个包含类对象的元组;如果传入非类对象作为第一个参数,将会引发TypeError异常。

2、元组参数:当第二个参数是元组时,元组应该只包含类对象;如果元组中包含非类对象,同样会抛出TypeError错误。

3、继承关系:issubclass()函数检查的是直接的或间接的继承关系;如果一个类是另一个类的子类(直接或间接),issubclass()函数将返回True。注意,一个类总是其自身的子类,所以issubclass(A, A)将返回True。

4、切勿过度使用:尽管issubclass()函数在某些场景下非常有用,但过度使用它可能会使代码变得复杂和难以维护;Python是一种动态类型的语言,通常更推荐使用鸭子类型(duck typing)而不是显式地检查类型。

5、接口检查:如果你需要检查一个类是否实现了特定的接口(即,是否包含特定的方法),使用hasattr()函数或dir()函数来检查方法的存在可能更合适;issubclass()函数仅检查继承关系,不检查类是否实现了特定的方法。

6、性能考虑:虽然issubclass()函数的性能通常是可接受的,但在性能敏感的代码中,如果你需要频繁地检查类的继承关系,可能需要考虑其他优化手段,比如缓存结果或使用其他数据结构来跟踪类的关系。

        总之,记住这些注意事项,可以帮助你更有效地使用issubclass()函数,并避免常见的错误和性能问题。

三、如何用好issubclass函数?

        在Python中,issubclass()函数是一个强大的工具,用于在运行时检查一个类是否是另一个类的子类,相关学习建议如下:

1、明确检查目的:在使用issubclass()函数之前,首先要明确你为何需要检查类的继承关系?是为了确保某个对象符合特定的接口?还是为了根据类型执行不同的逻辑?明确目的有助于你更准确地使用这个函数。

2、检验参数:确保你传递给issubclass()函数的参数是正确的,第一个参数应该是你想要检查的类,而第二个参数则是你期望的基类或基类的元组;如果参数不正确,你会遇到TypeError异常。

3、验查接口:虽然issubclass()是基于类的继承关系来工作的,但在Python中,更常见的做法是使用鸭子类型(duck typing),这意味着你通常应该基于对象的行为(即它们实现了哪些方法)而不是它们的类型来编写代码;只有在确实需要基于继承关系进行类型检查时,才使用issubclass()函数。

4、避免过度使用:过度使用issubclass()函数或其他类型检查机制可能导致代码变得复杂且难以维护;尝试设计你的代码以使其更加灵活和通用,而不是依赖于特定的类继承关系。

5、结合其他工具:issubclass()函数通常与其他Python特性一起使用,如抽象基类(ABCs)、元编程和动态类型检查,你可以结合这些工具来构建更强大和灵活的代码库。

6、错误消息集锦:如果你在代码中使用了issubclass()来执行类型检查,并在检查失败时抛出异常,确保提供清晰的错误消息,说明为什么类型检查失败以及如何解决问题。

7、单元测试代码:编写单元测试来验证你的issubclass()函数检查是否按预期工作,这有助于确保你的代码在不同的类继承关系下都能正确运行。

1、issubclass函数:
1-1、Python:
  1. # 1.函数:issubclass
  2. # 2.功能:用于判断类是否是另外一个类或者类型元组中任意类元素的子类
  3. # 3.语法:issubclass(class, classinfo)
  4. # 4.参数:
  5. # 4-1、class:类名,用于指定子类
  6. # 4-2、classinfo:类名,用于指定父类
  7. # 5.返回值:如果class是classinfo的子类,就返回True;反之,则返回False
  8. # 6.说明:在3.10版本发生变更: classinfo可以是一个union类型,即由多个父类组成的元组形式出现
  9. # 7.示例:
  10. # 利用dir()函数获取函数的相关内置属性和方法
  11. print(dir(issubclass))
  12. # ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
  13. # '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__',
  14. # '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__',
  15. # '__str__', '__subclasshook__', '__text_signature__']
  16. # 利用help()函数获取函数的文档信息
  17. help(issubclass)
  18. # 应用一:类型检查
  19. # 示例1:检查类是否是另一个类的直接子类
  20. class Base:
  21. pass
  22. class Derived(Base):
  23. pass
  24. def check_direct_subclass(cls, base):
  25. return issubclass(cls, base) and (cls != base)
  26. # 使用示例
  27. print(check_direct_subclass(Derived, Base))
  28. print(check_direct_subclass(Base, Derived))
  29. # True
  30. # False
  31. # 示例2:检查类是否是某个基类的子类(包括间接子类)
  32. class Base:
  33. pass
  34. class Derived(Base):
  35. pass
  36. class Grandchild(Derived):
  37. pass
  38. def check_subclass(cls, base):
  39. return issubclass(cls, base)
  40. # 使用示例
  41. print(check_subclass(Derived, Base))
  42. print(check_subclass(Grandchild, Base))
  43. print(check_subclass(Base, Base))
  44. # True
  45. # True
  46. # True
  47. # 示例3:检查类是否属于多个基类中的任何一个
  48. class Base1:
  49. pass
  50. class Base2:
  51. pass
  52. class Derived(Base1):
  53. pass
  54. def check_subclass_of_any(cls, *bases):
  55. return any(issubclass(cls, base) for base in bases)
  56. # 使用示例
  57. print(check_subclass_of_any(Derived, Base1, Base2))
  58. print(check_subclass_of_any(Base2, Base1, Base2))
  59. print(check_subclass_of_any(Base1, Base2))
  60. # True
  61. # True
  62. # False
  63. # 示例4:检查类是否不是任何指定基类的子类
  64. class Base1:
  65. pass
  66. class Base2:
  67. pass
  68. class Independent:
  69. pass
  70. def check_not_subclass_of(cls, *bases):
  71. return not any(issubclass(cls, base) for base in bases)
  72. # 使用示例
  73. print(check_not_subclass_of(Independent, Base1, Base2))
  74. print(check_not_subclass_of(Base1, Base2))
  75. print(check_not_subclass_of(Base2, Base1, Base2))
  76. # True
  77. # True
  78. # False
  79. # 应用二:设计模式
  80. # 示例1:工厂模式
  81. class Car:
  82. pass
  83. class ElectricCar(Car):
  84. pass
  85. class PetrolCar(Car):
  86. pass
  87. def car_factory(car_class):
  88. if issubclass(car_class, Car):
  89. return car_class()
  90. else:
  91. raise ValueError("Invalid car class")
  92. # 使用示例
  93. electric_car = car_factory(ElectricCar)
  94. petrol_car = car_factory(PetrolCar)
  95. # 尝试创建无效类型的汽车(将引发异常)
  96. # invalid_car = car_factory(str)
  97. # 示例2:策略模式
  98. class SortingStrategy:
  99. pass
  100. class BubbleSort(SortingStrategy):
  101. def sort(self, data):
  102. # Bubble sort implementation
  103. pass
  104. class QuickSort(SortingStrategy):
  105. def sort(self, data):
  106. # Quick sort implementation
  107. pass
  108. def sort_data(data, strategy_class):
  109. if issubclass(strategy_class, SortingStrategy):
  110. strategy = strategy_class()
  111. strategy.sort(data)
  112. else:
  113. raise ValueError("Invalid sorting strategy")
  114. # 使用示例
  115. data = [3, 6, 5, 8, 11, 10, 24, 10]
  116. sort_data(data, BubbleSort) # 使用冒泡排序
  117. sort_data(data, QuickSort) # 使用快速排序
  118. # 示例3:访问者模式
  119. class Element:
  120. def accept(self, visitor):
  121. pass
  122. class ConcreteElementA(Element):
  123. def accept(self, visitor):
  124. return visitor.visit_concrete_element_a(self)
  125. class ConcreteElementB(Element):
  126. def accept(self, visitor):
  127. return visitor.visit_concrete_element_b(self)
  128. class Visitor:
  129. pass
  130. class ConcreteVisitorA(Visitor):
  131. def visit_concrete_element_a(self, element):
  132. print(f"Visiting ConcreteElementA: {element}")
  133. def visit_concrete_element_b(self, element):
  134. print(f"Visiting ConcreteElementB: {element}")
  135. def visit_elements(elements, visitor_class):
  136. if issubclass(visitor_class, Visitor):
  137. visitor = visitor_class()
  138. for element in elements:
  139. element.accept(visitor)
  140. else:
  141. raise ValueError("Invalid visitor class")
  142. # 使用示例
  143. elements = [ConcreteElementA(), ConcreteElementB()]
  144. visit_elements(elements, ConcreteVisitorA)
  145. # Visiting ConcreteElementA: <__main__.ConcreteElementA object at 0x000002A5F8FDEB50>
  146. # Visiting ConcreteElementB: <__main__.ConcreteElementB object at 0x000002A5F8FDEB90>
  147. # 应用三:异常处理
  148. # 示例1:检查异常类型
  149. class MyCustomException(Exception):
  150. pass
  151. class MySpecificException(MyCustomException):
  152. pass
  153. def handle_exception(exc):
  154. if issubclass(type(exc), MyCustomException):
  155. print("Handling a custom exception")
  156. else:
  157. print("Handling a generic exception")
  158. try:
  159. raise MySpecificException("This is a specific exception")
  160. except Exception as e:
  161. handle_exception(e)
  162. try:
  163. raise ValueError("This is a built-in exception")
  164. except Exception as e:
  165. handle_exception(e)
  166. # Handling a custom exception
  167. # Handling a generic exception
  168. # 示例2:多个异常类型检查
  169. class MyCustomException1(Exception):
  170. pass
  171. class MyCustomException2(Exception):
  172. pass
  173. def handle_specific_exceptions(exc):
  174. if issubclass(type(exc), (MyCustomException1, MyCustomException2)):
  175. print("Handling a specific custom exception")
  176. else:
  177. print("Handling a generic exception")
  178. try:
  179. raise MyCustomException1("This is a custom exception 1")
  180. except Exception as e:
  181. handle_specific_exceptions(e)
  182. try:
  183. raise ValueError("This is a built-in exception")
  184. except Exception as e:
  185. handle_specific_exceptions(e)
  186. # Handling a specific custom exception
  187. # Handling a generic exception
  188. # 示例3:异常链(Python 3中引入)
  189. class MyCustomException(Exception):
  190. pass
  191. class AnotherCustomException(Exception):
  192. pass
  193. def handle_exception(exc):
  194. # 检查是否是自定义异常
  195. if issubclass(type(exc), MyCustomException):
  196. print("Handling a custom exception of type:", type(exc).__name__)
  197. # 检查是否有原始异常,并处理它
  198. if exc.__cause__ is not None:
  199. print("Original exception:", type(exc.__cause__).__name__)
  200. # 可以递归调用handle_exception来处理原始异常
  201. # handle_exception(exc.__cause__)
  202. else:
  203. print("Handling a generic exception")
  204. try:
  205. try:
  206. # 假设这里引发了一个内置异常
  207. raise ValueError("Invalid value")
  208. except ValueError as e:
  209. # 在这里,我们引发一个自定义异常,并链接到原始异常
  210. raise MyCustomException("A problem occurred") from e
  211. except MyCustomException as mce:
  212. # 处理自定义异常
  213. handle_exception(mce)
  214. try:
  215. # 直接引发一个自定义异常,没有原始异常
  216. raise AnotherCustomException("Another problem occurred")
  217. except Exception as e:
  218. # 处理所有其他异常
  219. handle_exception(e)
  220. # Handling a custom exception of type: MyCustomException
  221. # Original exception: ValueError
  222. # Handling a generic exception
  223. # 应用四:反射
  224. # 示例1:检查类继承关系
  225. class BaseClass:
  226. pass
  227. class DerivedClass(BaseClass):
  228. pass
  229. def check_inheritance(cls, base_cls):
  230. return issubclass(cls, base_cls)
  231. # 使用示例
  232. print(check_inheritance(DerivedClass, BaseClass))
  233. print(check_inheritance(BaseClass, DerivedClass))
  234. # True
  235. # False
  236. # 示例2:使用globals()或locals()进行反射
  237. class MyClass:
  238. pass
  239. def reflect_on_classes():
  240. # 获取当前作用域内的所有变量
  241. all_vars = globals()
  242. # 查找并打印所有MyClass的子类
  243. for name, obj in all_vars.items():
  244. if isinstance(obj, type) and issubclass(obj, MyClass) and obj is not MyClass:
  245. print(f"{name} is a subclass of MyClass")
  246. # 定义MyClass的子类
  247. class SubClass1(MyClass):
  248. pass
  249. class SubClass2(MyClass):
  250. pass
  251. # 执行反射函数
  252. reflect_on_classes()
  253. # SubClass1 is a subclass of MyClass
  254. # SubClass2 is a subclass of MyClass
  255. # 示例3:动态加载模块并检查类关系
  256. import importlib
  257. def check_class_in_module(module_name, class_name, base_class):
  258. # 动态加载模块
  259. module = importlib.import_module(module_name)
  260. # 获取类对象
  261. cls = getattr(module, class_name, None)
  262. # 检查类是否存在并且是base_class的子类
  263. if cls is not None and issubclass(cls, base_class):
  264. print(f"{class_name} in {module_name} is a subclass of {base_class.__name__}")
  265. else:
  266. print(f"No {class_name} found in {module_name} or it is not a subclass of {base_class.__name__}")
  267. # 使用示例
  268. check_class_in_module('collections', 'abc.Container', object)
  269. # No abc.Container found in collections or it is not a subclass of object
  270. # 应用五:文档生成
  271. class Animal:
  272. pass
  273. class Animal:
  274. pass
  275. class Mammal(Animal):
  276. pass
  277. class Reptile(Animal):
  278. pass
  279. class Dog(Mammal):
  280. pass
  281. class Snake(Reptile):
  282. pass
  283. import inspect
  284. def generate_class_hierarchy_docs(base_class, module=None):
  285. """
  286. Generate a documentation string for the class hierarchy starting from the given base class.
  287. :param base_class: The base class to start generating the hierarchy for.
  288. :param module: The module to search for classes (defaults to the current module).
  289. :return: None (prints the hierarchy to the console).
  290. """
  291. if module is None:
  292. module = inspect.getmodule(base_class)
  293. print(f"Class Hierarchy for {base_class.__name__}:")
  294. print("-" * len(base_class.__name__) + "-")
  295. for name, cls in inspect.getmembers(module, inspect.isclass):
  296. if issubclass(cls, base_class) and cls is not base_class:
  297. def print_inheritance_chain(cls, indent=""):
  298. print(f"{indent}{cls.__name__}")
  299. for base in cls.__bases__:
  300. if issubclass(base, Animal): # Only print Animal subclasses in the chain
  301. print_inheritance_chain(base, indent + " ")
  302. print_inheritance_chain(cls)
  303. print() # Separate different subclasses with a newline
  304. # 生成Animal类的继承关系文档
  305. generate_class_hierarchy_docs(Animal)
  306. # Class Hierarchy for Animal:
  307. # -------
  308. # Dog
  309. # Mammal
  310. # Animal
  311. #
  312. # Mammal
  313. # Animal
  314. #
  315. # Reptile
  316. # Animal
  317. #
  318. # Snake
  319. # Reptile
  320. # Animal
  321. # 应用六:框架和库开发
  322. # 示例1:确保用户提供的类继承自特定的基类
  323. class Shape:
  324. pass
  325. def register_shape_class(cls):
  326. if not issubclass(cls, Shape):
  327. raise ValueError(f"{cls.__name__} does not inherit from Shape")
  328. # 注册类到图形库中的代码...
  329. print(f"Registered {cls.__name__} as a shape class.")
  330. # 用户提供的类
  331. class Circle(Shape):
  332. pass
  333. class Triangle:
  334. pass
  335. # 注册Circle类,这是合法的
  336. register_shape_class(Circle) # 输出: Registered Circle as a shape class.
  337. # 尝试注册Triangle类,这将引发错误
  338. try:
  339. register_shape_class(Triangle)
  340. except ValueError as e:
  341. print(e) # 输出: Triangle does not inherit from Shape
  342. # Registered Circle as a shape class.
  343. # Triangle does not inherit from Shape
  344. # 示例2:检查接口兼容性
  345. class DataProcessor:
  346. @staticmethod
  347. def process_data(data):
  348. raise NotImplementedError("Subclasses must implement this method")
  349. def is_data_processor(cls):
  350. return (
  351. issubclass(cls, DataProcessor) and
  352. callable(getattr(cls, "process_data", None))
  353. )
  354. class MyDataProcessor(DataProcessor):
  355. @staticmethod
  356. def process_data(data):
  357. return data * 2
  358. class AnotherClass:
  359. pass
  360. # 检查MyDataProcessor是否实现了DataProcessor接口
  361. print(is_data_processor(MyDataProcessor))
  362. # 检查AnotherClass是否实现了DataProcessor接口
  363. print(is_data_processor(AnotherClass))
  364. # True
  365. # False
  366. # 示例3:在框架中使用插件系统
  367. class PluginBase:
  368. def initialize(self):
  369. pass
  370. def execute(self, data):
  371. pass
  372. def load_plugin(plugin_cls):
  373. if not issubclass(plugin_cls, PluginBase):
  374. raise TypeError(f"{plugin_cls.__name__} is not a valid plugin class")
  375. # 加载插件的代码...
  376. plugin_instance = plugin_cls()
  377. plugin_instance.initialize()
  378. return plugin_instance
  379. # 用户提供的插件类
  380. class MyPlugin(PluginBase):
  381. def initialize(self):
  382. print("Initializing MyPlugin")
  383. def execute(self, data):
  384. print(f"Executing with data: {data}")
  385. # 加载并初始化插件
  386. plugin = load_plugin(MyPlugin)
  387. plugin.execute("Some data")
  388. # Initializing MyPlugin
  389. # Executing with data: Some data
  390. # 应用七:测试和调试
  391. # 示例1:基本继承关系测试
  392. class Base:
  393. pass
  394. class Derived(Base):
  395. pass
  396. class AnotherDerived(Base):
  397. pass
  398. # 测试继承关系
  399. assert issubclass(Derived, Base), "Derived should be a subclass of Base"
  400. assert issubclass(AnotherDerived, Base), "AnotherDerived should be a subclass of Base"
  401. assert not issubclass(Base, Derived), "Base should not be a subclass of Derived"
  402. print("Inheritance tests passed")
  403. # Inheritance tests passed
  404. # 示例2:测试多重继承
  405. class A:
  406. pass
  407. class B:
  408. pass
  409. class C(A, B):
  410. pass
  411. # 测试多重继承
  412. assert issubclass(C, A), "C should be a subclass of A"
  413. assert issubclass(C, B), "C should be a subclass of B"
  414. print("Multiple inheritance tests passed")
  415. # Multiple inheritance tests passed
  416. # 示例3:使用isinstance与issubclass结合进行调试
  417. class MyClass:
  418. pass
  419. obj = MyClass()
  420. # 使用isinstance检查实例关系
  421. assert isinstance(obj, MyClass), "obj should be an instance of MyClass"
  422. # 使用issubclass检查子类关系(这里只是为了展示,通常不这么用)
  423. assert issubclass(MyClass, object), "MyClass should be a subclass of object"
  424. print("Instance and subclass checks passed")
  425. # Instance and subclass checks passed
  426. # 示例4:使用unittest模块进行单元测试
  427. import unittest
  428. class TestInheritance(unittest.TestCase):
  429. def test_basic_inheritance(self):
  430. class Base:
  431. pass
  432. class Derived(Base):
  433. pass
  434. self.assertTrue(issubclass(Derived, Base), "Derived should be a subclass of Base")
  435. def test_multiple_inheritance(self):
  436. class A:
  437. pass
  438. class B:
  439. pass
  440. class C(A, B):
  441. pass
  442. self.assertTrue(issubclass(C, A), "C should be a subclass of A")
  443. self.assertTrue(issubclass(C, B), "C should be a subclass of B")
  444. def test_not_subclass(self):
  445. class A:
  446. pass
  447. class B:
  448. pass
  449. self.assertFalse(issubclass(A, B), "A should not be a subclass of B")
  450. if __name__ == '__main__':
  451. unittest.main()
  452. # E:\python_workspace\pythonProject\.venv\Scripts\python.exe "E:/Program Files/JetBrains/PyCharm Community Edition 2023.3/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path E:\python_workspace\pythonProject\test2.py
  453. # Testing started at 21:10 ...
  454. # Launching unittests with arguments python -m unittest E:\python_workspace\pythonProject\test2.py in E:\python_workspace\pythonProject
  455. #
  456. #
  457. #
  458. # Ran 3 tests in 0.004s
  459. #
  460. # OK
  461. # 应用八:元类编程
  462. # 示例1:定义一个简单的元类,并检查继承关系
  463. class Meta(type):
  464. def __init__(cls, name, bases, dct):
  465. super().__init__(name, bases, dct)
  466. print(f"Creating class {name}")
  467. # 检查继承关系
  468. for base in bases:
  469. if issubclass(base, object):
  470. print(f"{name} inherits from {base.__name__}")
  471. class MyClass(metaclass=Meta):
  472. pass
  473. class MyOtherClass(MyClass):
  474. pass
  475. # 输出将显示类的创建和继承关系
  476. # Creating class MyClass
  477. # Creating class MyOtherClass
  478. # MyOtherClass inherits from MyClass
  479. # 示例2:使用元类自动注册子类
  480. class RegistryMeta(type):
  481. _registry = {}
  482. def __init__(cls, name, bases, dct):
  483. super().__init__(name, bases, dct)
  484. # 如果是直接继承自基类(不是继承自其他派生类),则注册
  485. if not any(issubclass(b, cls) for b in cls.__bases__):
  486. RegistryMeta._registry[name] = cls
  487. @classmethod
  488. def get_subclass(cls, name):
  489. return cls._registry.get(name)
  490. class BaseClass(metaclass=RegistryMeta):
  491. pass
  492. class SubClass1(BaseClass):
  493. pass
  494. class SubClass2(BaseClass):
  495. pass
  496. # 检查并获取子类
  497. subclass1 = RegistryMeta.get_subclass('SubClass1')
  498. print(subclass1 is SubClass1)
  499. # 检查继承关系
  500. print(issubclass(SubClass1, BaseClass))
  501. # True
  502. # True
1-2、VBA
略,待后补。
2、推荐阅读:

1、Python-VBA函数之旅-isinstance()函数

Python算法之旅:Algorithm

Python函数之旅:Functions 

个人主页:神奇夜光杯-CSDN博客 
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号