首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Python-VBA函数之旅-isinstance函数

  • 25-03-03 04:43
  • 3285
  • 9989
blog.csdn.net

目录

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

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

三、如何用好isinstance函数?

1、isinstance函数:

1-1、Python:

1-2、VBA:

2、推荐阅读:

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



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

        在Python中,isinstance()函数用于确定对象是否属于特定的类或类型,常见的应用场景有:

1、类型检查:当你需要根据对象的类型执行不同的操作时,isinstance()函数非常有用。例如,你可能需要根据变量的类型来格式化输出,或者根据类型执行不同的逻辑分支。

2、多态性支持:在面向对象的编程中,多态性允许使用父类引用处理子类对象;使用isinstance()函数可以确保即使子类有额外的行为或属性,代码也能正确处理它们。 

3、输入验证:在编写函数或方法时,你可能需要确保传入的参数是预期的类型。使用isinstance()可以在函数内部进行类型检查,并在传入错误类型时提供清晰的错误信息。

4、扩展性和灵活性:当你想让你的代码能够处理多种类型时,可以使用isinstance()函数来检查一个对象是否属于一系列类型中的任何一个,这使得代码更加灵活,能够处理更多种类的输入。

5、工厂模式:在工厂模式中,isinstance()函数可以用来确定应该创建哪种类型的对象;工厂函数接受一些参数,并使用isinstance()来确定应该返回哪种类型的对象实例。

6、类型安全的API设计:在设计API或库时,确保传入的参数类型正确是很重要的;使用isinstance()可以帮助你实现类型安全的接口,从而避免潜在的错误和异常。

7、与抽象基类(ABC)一起使用:在设计API或库时,确保传入的参数类型正确是很重要的,使用isinstance()函数可以帮助你实现类型安全的接口,从而避免潜在的错误和异常。

        总之,isinstance()函数在Python编程中是一个强大的工具,用于在运行时确定对象的类型,并根据需要执行相应的操作,它在类型检查、多态性实现、输入验证、扩展性和灵活性、工厂模式、设计类型安全的API及与抽象基类(ABC)一起使用等方面都有广泛的应用。

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

        在Python中,isinstance()函数是一个常用的工具,用于确定一个对象是否是一个已知的类型或类的实例。使用时,需注意以下几点:

1、类型元组:当你想检查对象是否属于多个类型之一时,可以传递一个类型元组给 isinstance(),确保元组中的类型是按照你的逻辑顺序排列的,因为一旦找到匹配的类型,isinstance()函数就会返回 True,并不会继续检查元组中的其他类型。

2、不要过度使用:尽管isinstance()函数很有用,但过度使用它可能会导致代码变得冗长和难以阅读。在某些情况下,使用更简洁的鸭子类型(duck typing)可能是更好的选择,即“如果它走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子”。这意味着,如果对象有你需要的方法或属性,你就可以使用它,而不必关心它确切的类型。

3、继承关系:当使用isinstance()检查一个对象是否是一个类的实例时,它也会检查该对象是否是该类子类的实例,这是多态性的基础,但也要确保你了解类的继承关系,以避免意外的类型匹配。

4、自定义类的比较:如果你定义了自己的类,并且想要通过isinstance()检查对象是否是你的类的实例,确保你的类定义正确,并且没有意外地覆盖了 `__instancecheck__` 方法,该方法会影响 isinstance()的行为。通常,你不需要直接操作这个方法,除非你有特殊的类型检查需求。

5、避免与type()函数比较:isinstance()和type()都可以用来检查对象的类型,但isinstance()更为推荐,因为它可以处理继承关系;而type()只会检查对象是否直接是某个特定类的实例,不会考虑继承。

6、性能考虑:虽然isinstance()函数的性能通常不是问题,但在性能关键的应用程序中,频繁的类型检查可能会对性能产生轻微影响。在这种情况下,可以考虑使用其他设计策略来减少类型检查的需要,比如使用接口或协议来定义对象的行为。

7、版本兼容性:不同版本的Python可能对isinstance()的行为有细微的差别,特别是当涉及到内置类型或特殊的元类行为时,确保你的代码在目标Python版本上进行了充分的测试。

        总之,只有遵循这些注意事项,你才可以更安全、更有效地使用isinstance()函数来进行类型检查。

三、如何用好isinstance函数?

        要在Python中用好isinstance()函数,你需要理解其用途、语法以及一些常见的应用场景,相关参考建议如下:

1、明确使用场景:首先,你需要明确为什么要使用isinstance()函数。通常,这是为了确定一个对象是否属于特定的类型或类的实例,这在你需要基于对象的类型执行不同操作时特别有用。

2、理解语法:isinstance()函数接受两个参数:要检查的对象和要比较的类型(或类型元组);如果对象是该类型的实例,则返回True,否则返回False。

3、处理继承关系:当使用isinstance()时,它会考虑继承关系,这意味着如果一个对象是一个类的子类实例,那么isinstance()也会返回True,这是多态性的一个体现,有助于编写更加灵活和可维护的代码。

4、检查多个类型:如果你想要检查对象是否属于多个可能的类型之一,可以将这些类型放在一个元组中,并将其作为第二个参数传递给isinstance()函数。

5、避免过度使用:虽然isinstance()在某些情况下很有用,但过度使用它可能会导致代码变得冗长和难以维护;在Python中,通常更倾向于使用鸭子类型(duck typing),即如果对象具有你所需的方法或属性,就可以认为它是合适的类型,而无需显式检查其类型。

6、结合异常处理:如果你期望对象必须是特定类型,并且如果不是该类型则程序无法继续执行,可以结合使用isinstance()和异常处理来确保类型正确。

7、考虑使用抽象基类:对于更复杂的类型检查,可以考虑使用Python的`collections.abc`模块中定义的抽象基类(ABCs),这些基类提供了更高级别的接口检查,而不仅仅是简单的类型匹配。

8、注意版本兼容性:不同的Python版本可能对isinstance()的行为略有不同,确保你的代码在目标Python版本上进行了充分的测试,并检查是否有任何与类型检查相关的已知变化。

9、代码清晰性:使用isinstance()时,确保你的代码清晰易读,避免在复杂的逻辑表达式中嵌套多个isinstance()调用,这可能会使代码难以理解;相反,考虑将类型检查逻辑分解为单独的函数或方法,以提高代码的可读性和可维护性。

        总之,只有通过遵循这些建议,你才能更有效地使用isinstance()函数来增强你的Python代码的类型安全性和灵活性。

1、isinstance函数:
1-1、Python:
  1. # 1.函数:isinstance
  2. # 2.功能:用于判断对象是否是类或者类型元组中任意类元素的实例
  3. # 3.语法:isinstance(object, classinfo)
  4. # 4.参数:
  5. # 4-1、object:实例对象
  6. # 4-2、classinfo:类名可以是直接或间接类名、基本类型或者由它们组成的元组
  7. # 5.返回值:如果对象的类型与classinfo类型相同则返回True;否则返回False
  8. # 6.说明:
  9. # 7.示例:
  10. # 利用dir()函数获取函数的相关内置属性和方法
  11. # ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
  12. # '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__',
  13. # '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__',
  14. # '__str__', '__subclasshook__', '__text_signature__']
  15. print(dir(isinstance))
  16. # 利用help()函数获取函数的文档信息
  17. help(isinstance)
  18. # 应用一:类型检查
  19. # 示例1:检查整数类型
  20. num = 123
  21. if isinstance(num, int):
  22. print("num 是一个整数")
  23. else:
  24. print("num 不是一个整数")
  25. # num 是一个整数
  26. # 示例2:检查字符串类型
  27. text = "Hello, Python!"
  28. if isinstance(text, str):
  29. print("text 是一个字符串")
  30. else:
  31. print("text 不是一个字符串")
  32. # text 是一个字符串
  33. # 示例3:检查列表类型
  34. my_list = [3, 5, 6, 8, 10, 11, 24]
  35. if isinstance(my_list, list):
  36. print("my_list 是一个列表")
  37. else:
  38. print("my_list 不是一个列表")
  39. # my_list 是一个列表
  40. # 示例4:检查多个类型
  41. item = "Myelsa"
  42. if isinstance(item, (str, int)):
  43. print("item 是字符串或整数")
  44. else:
  45. print("item 不是字符串也不是整数")
  46. # item 是字符串或整数
  47. # 示例5:自定义类型检查
  48. class MyClass:
  49. pass
  50. obj = MyClass()
  51. if isinstance(obj, MyClass):
  52. print("obj 是 MyClass 的一个实例")
  53. else:
  54. print("obj 不是 MyClass 的一个实例")
  55. # obj 是 MyClass 的一个实例
  56. # 应用二:多态性支持
  57. # 示例1:形状类与多态性
  58. class Shape:
  59. def draw(self):
  60. pass
  61. class Circle(Shape):
  62. def draw(self):
  63. print("Drawing a circle")
  64. class Rectangle(Shape):
  65. def draw(self):
  66. print("Drawing a rectangle")
  67. class Triangle(Shape):
  68. def draw(self):
  69. print("Drawing a triangle")
  70. def draw_shapes(shapes):
  71. for shape in shapes:
  72. if isinstance(shape, Circle):
  73. print("Drawing a circle specifically")
  74. shape.draw()
  75. elif isinstance(shape, Rectangle):
  76. print("Drawing a rectangle specifically")
  77. shape.draw()
  78. elif isinstance(shape, Triangle):
  79. print("Drawing a triangle specifically")
  80. shape.draw()
  81. else:
  82. print("Drawing a generic shape")
  83. shape.draw()
  84. shapes = [Circle(), Rectangle(), Triangle()]
  85. draw_shapes(shapes)
  86. # Drawing a circle specifically
  87. # Drawing a circle
  88. # Drawing a rectangle specifically
  89. # Drawing a rectangle
  90. # Drawing a triangle specifically
  91. # Drawing a triangle
  92. # 示例2:使用多态性处理不同数据类型的函数
  93. def process_data(data):
  94. if isinstance(data, int):
  95. print(f"Processing integer: {data}")
  96. # 执行整数相关的操作
  97. elif isinstance(data, str):
  98. print(f"Processing string: {data}")
  99. # 执行字符串相关的操作
  100. elif isinstance(data, list):
  101. print(f"Processing list: {data}")
  102. # 执行列表相关的操作
  103. else:
  104. print(f"Unsupported data type: {type(data)}")
  105. process_data(42)
  106. process_data("Hello")
  107. process_data([1, 2, 3])
  108. process_data(3.14)
  109. # Processing integer: 42
  110. # Processing string: Hello
  111. # Processing list: [1, 2, 3]
  112. # Unsupported data type:
  113. # 应用三:输入验证
  114. # 示例1:验证整数输入
  115. def validate_integer_input(input_value):
  116. if isinstance(input_value, int):
  117. print("输入是一个整数")
  118. return True
  119. else:
  120. print("输入不是一个整数,请重新输入")
  121. return False
  122. # 测试函数
  123. user_input = input("请输入一个整数: ")
  124. try:
  125. user_input = int(user_input) # 尝试将输入转换为整数
  126. if validate_integer_input(user_input):
  127. # 如果验证通过,进行后续操作
  128. pass # 在这里添加你的代码
  129. except ValueError:
  130. # 如果输入无法转换为整数,打印错误信息
  131. print("无效的输入,请输入一个有效的整数")
  132. # 请输入一个整数: 1024
  133. # 输入是一个整数
  134. # 示例2:验证字符串输入
  135. def validate_string_input(input_value):
  136. if isinstance(input_value, str):
  137. print("输入是一个字符串")
  138. return True
  139. else:
  140. print("输入不是一个字符串,请重新输入")
  141. return False
  142. # 测试函数
  143. user_input = input("请输入一个字符串: ")
  144. if validate_string_input(user_input):
  145. # 如果验证通过,进行后续操作
  146. pass # 在这里添加你的代码
  147. # 请输入一个字符串: myelsa
  148. # 输入是一个字符串
  149. # 示例3:验证列表输入,并检查元素类型
  150. def validate_list_input(input_value):
  151. if isinstance(input_value, list):
  152. for item in input_value:
  153. if not isinstance(item, int):
  154. print("列表中包含非整数元素")
  155. return False
  156. print("输入是一个整数列表")
  157. return True
  158. else:
  159. print("输入不是一个列表,请重新输入")
  160. return False
  161. # 测试函数
  162. user_input = input("请输入一个由整数组成的列表(用空格分隔): ")
  163. try:
  164. user_input_list = list(map(int, user_input.split())) # 将输入转换为整数列表
  165. if validate_list_input(user_input_list):
  166. # 如果验证通过,进行后续操作
  167. pass # 在这里添加你的代码
  168. except ValueError:
  169. # 如果输入无法转换为整数列表,打印错误信息
  170. print("无效的输入,请输入一个由整数组成的列表")
  171. # 请输入一个由整数组成的列表(用空格分隔): 3 5 6
  172. # 输入是一个整数列表
  173. # 示例4:验证自定义类实例的输入
  174. class Person:
  175. def __init__(self, name, age):
  176. self.name = name
  177. self.age = age
  178. def validate_person_input(input_value):
  179. if isinstance(input_value, Person):
  180. print("输入是一个 Person 类的实例")
  181. return True
  182. else:
  183. print("输入不是一个 Person 类的实例,请重新输入")
  184. return False
  185. # 测试函数
  186. user_name = input("请输入姓名: ")
  187. user_age = input("请输入年龄: ")
  188. try:
  189. user_age = int(user_age) # 尝试将年龄输入转换为整数
  190. person = Person(user_name, user_age)
  191. if validate_person_input(person):
  192. # 如果验证通过,进行后续操作
  193. pass # 在这里添加你的代码
  194. except ValueError:
  195. # 如果年龄输入无法转换为整数,打印错误信息
  196. print("无效的输入,年龄必须是一个整数")
  197. # 请输入姓名: Myelsa
  198. # 请输入年龄: 18
  199. # 输入是一个 Person 类的实例
  200. # 应用四:扩展性和灵活性
  201. # 示例1:处理不同数据类型的函数
  202. def process_data(data):
  203. if isinstance(data, int):
  204. print(f"Processing an integer: {data}")
  205. # 执行整数相关的操作
  206. elif isinstance(data, str):
  207. print(f"Processing a string: {data}")
  208. # 执行字符串相关的操作
  209. elif isinstance(data, list):
  210. print(f"Processing a list: {data}")
  211. # 执行列表相关的操作
  212. elif isinstance(data, (dict, set)):
  213. print(f"Processing a collection: {data}")
  214. # 执行集合或字典相关的操作
  215. else:
  216. print(f"Unsupported data type: {type(data)}")
  217. # 使用函数处理不同类型的数据
  218. process_data(42)
  219. process_data("Hello")
  220. process_data([1, 2, 3])
  221. process_data({"key": "value"})
  222. process_data({1, 2, 3})
  223. # Processing an integer: 42
  224. # Processing a string: Hello
  225. # Processing a list: [1, 2, 3]
  226. # Processing a collection: {'key': 'value'}
  227. # Processing a collection: {1, 2, 3}
  228. # 示例2:插件式架构
  229. class PluginInterface:
  230. def execute(self):
  231. raise NotImplementedError("Subclasses must implement this method")
  232. class PluginA(PluginInterface):
  233. def execute(self):
  234. print("Plugin A is executing")
  235. class PluginB(PluginInterface):
  236. def execute(self):
  237. print("Plugin B is executing")
  238. def run_plugin(plugin):
  239. if isinstance(plugin, PluginInterface):
  240. plugin.execute()
  241. else:
  242. print("The provided plugin does not implement the required interface")
  243. # 创建插件实例并运行它们
  244. plugin_a = PluginA()
  245. plugin_b = PluginB()
  246. run_plugin(plugin_a)
  247. run_plugin(plugin_b)
  248. # Plugin A is executing
  249. # Plugin B is executing
  250. # 示例3:工厂模式
  251. class Shape:
  252. pass
  253. class Circle(Shape):
  254. def draw(self):
  255. print("Drawing a circle")
  256. class Rectangle(Shape):
  257. def draw(self):
  258. print("Drawing a rectangle")
  259. def create_shape(shape_type):
  260. if isinstance(shape_type, str):
  261. if shape_type == "circle":
  262. return Circle()
  263. elif shape_type == "rectangle":
  264. return Rectangle()
  265. else:
  266. print("Invalid shape type")
  267. return None
  268. # 使用工厂函数创建形状对象
  269. circle = create_shape("circle")
  270. rectangle = create_shape("rectangle")
  271. if circle:
  272. circle.draw()
  273. if rectangle:
  274. rectangle.draw()
  275. # Drawing a circle
  276. # Drawing a rectangle
  277. # 应用五:类型安全的API设计
  278. # 示例1:简单的API函数
  279. def greet_person(name: str):
  280. if not isinstance(name, str):
  281. raise ValueError("Name must be a string")
  282. print(f"Hello, {name}!")
  283. # 正确使用
  284. greet_person("Myelsa")
  285. # Hello, Myelsa!
  286. # 错误使用,会抛出异常
  287. greet_person(42)
  288. # ValueError: Name must be a string
  289. # 示例2:带有多个参数和返回类型的API函数
  290. def calculate_area(shape: str, **kwargs) -> float:
  291. if not isinstance(shape, str):
  292. raise ValueError("Shape must be a string")
  293. if shape == "circle":
  294. if not all(isinstance(v, (int, float)) for k, v in kwargs.items()):
  295. raise ValueError("Circle parameters must be numeric")
  296. radius = kwargs.get("radius", 0)
  297. return 3.14159 * radius ** 2
  298. elif shape == "rectangle":
  299. if not all(isinstance(v, (int, float)) for k, v in kwargs.items()):
  300. raise ValueError("Rectangle parameters must be numeric")
  301. length = kwargs.get("length", 0)
  302. width = kwargs.get("width", 0)
  303. return length * width
  304. else:
  305. raise ValueError("Invalid shape")
  306. # 正确使用
  307. area_circle = calculate_area("circle", radius=5) # 输出圆的面积
  308. area_rectangle = calculate_area("rectangle", length=10, width=5) # 输出矩形的面积
  309. # 错误使用,会抛出异常
  310. calculate_area("triangle", base=3, height=4) # 抛出 ValueError: Invalid shape
  311. calculate_area("circle", radius="five") # 抛出 ValueError: Circle parameters must be numeric
  312. # 示例3:使用类进行API设计
  313. class BankAccount:
  314. def __init__(self, name: str, balance: float):
  315. if not isinstance(name, str):
  316. raise ValueError("Name must be a string")
  317. if not isinstance(balance, (int, float)):
  318. raise ValueError("Balance must be a number")
  319. self.name = name
  320. self.balance = balance
  321. def deposit(self, amount: float):
  322. if not isinstance(amount, (int, float)):
  323. raise ValueError("Deposit amount must be a number")
  324. if amount < 0:
  325. raise ValueError("Deposit amount must be positive")
  326. self.balance += amount
  327. print(f"Deposited {amount}. New balance: {self.balance}")
  328. def withdraw(self, amount: float):
  329. if not isinstance(amount, (int, float)):
  330. raise ValueError("Withdraw amount must be a number")
  331. if amount < 0:
  332. raise ValueError("Withdraw amount must be positive")
  333. if amount > self.balance:
  334. raise ValueError("Insufficient funds")
  335. self.balance -= amount
  336. print(f"Withdrawn {amount}. New balance: {self.balance}")
  337. # 创建一个银行账户实例
  338. account = BankAccount("Alice", 1000.0)
  339. # 正确使用
  340. account.deposit(500.0) # 存款
  341. account.withdraw(200.0) # 取款
  342. # Deposited 500.0. New balance: 1500.0
  343. # Withdrawn 200.0. New balance: 1300.0
  344. # 错误使用,会抛出异常
  345. account.withdraw(-100.0) # 抛出 ValueError: Withdraw amount must be positive
  346. account.withdraw(1500.0) # 抛出 ValueError: Insufficient funds
  347. # 应用六:与抽象基类(ABC)一起使用
  348. from abc import ABC, abstractmethod
  349. class Shape(ABC):
  350. @abstractmethod
  351. def area(self):
  352. pass
  353. class Circle(Shape):
  354. def __init__(self, radius):
  355. self.radius = radius
  356. def area(self):
  357. return 3.14 * self.radius ** 2
  358. class Rectangle(Shape):
  359. def __init__(self, length, width):
  360. self.length = length
  361. self.width = width
  362. def area(self):
  363. return self.length * self.width
  364. def check_shape(obj):
  365. if isinstance(obj, Shape):
  366. print("The object is an instance of Shape or one of its subclasses.")
  367. try:
  368. area = obj.area()
  369. print(f"The area of the shape is: {area}")
  370. except TypeError:
  371. print("The shape object does not have a valid area method.")
  372. else:
  373. print("The object is not an instance of Shape or one of its subclasses.")
  374. # 测试 Circle 和 Rectangle
  375. circle = Circle(5)
  376. check_shape(circle)
  377. rectangle = Rectangle(10, 5)
  378. check_shape(rectangle)
  379. # 测试一个非 Shape 类的实例
  380. not_a_shape = "I'm not a shape"
  381. check_shape(not_a_shape)
  382. # The object is an instance of Shape or one of its subclasses.
  383. # The area of the shape is: 78.5
  384. # The object is an instance of Shape or one of its subclasses.
  385. # The area of the shape is: 50
  386. # The object is not an instance of Shape or one of its subclasses.
1-2、VBA:
略,待后补。
2、推荐阅读:

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

Python算法之旅:Algorithm

Python函数之旅:Functions 

个人主页:神奇夜光杯-CSDN博客 
文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览60609 人正在系统学习中
遨游码海,我心飞扬
微信名片
注:本文转载自blog.csdn.net的神奇夜光杯的文章"https://myelsa1024.blog.csdn.net/article/details/138149092"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top