python: the assret incident

anthonywritescode
13 Aug 202513:38

Summary

TLDR在本视频中,讲解者深入探讨了Python中的设计问题,特别是关于命名元组(namedtuple)和模拟对象(mock)的问题。通过对比命名元组、数据类(dataclasses)以及模拟对象的命名空间问题,讲解了Python如何通过分离方法与属性来避免冲突。尤其关注了模拟对象中的‘asset’问题,讲解了Python如何在版本3.5中通过‘unsafe’属性解决了命名空间冲突问题。视频通过这些实例展示了Python设计中的优缺点,并分享了如何从中吸取教训以避免潜在错误。

Takeaways

  • 😀 Python的NameTuple类设计存在一些问题,尤其是在与用户自定义字段命名冲突时。
  • 😀 NameTuple类的字段方法以'_'开头,目的是避免与用户定义的字段名冲突,这样可以为它们提供命名空间。
  • 😀 Python的DataClass类通过分离方法和模块功能,避免了与用户命名空间的冲突,提供了更清晰的结构。
  • 😀 DataClass通过类型注解自动创建类,并将常见方法(如字段处理)提取到模块级函数中,避免了重复和冲突。
  • 😀 Python的mock对象也有类似的问题:它允许动态添加属性和方法,这可能导致测试中未被注意的错误。
  • 😀 mock对象中,断言方法(如assert called once)可能会因拼写错误而静默通过,这会导致测试假通过。
  • 😀 Python 3.5引入了名为'unsafe'的新特性,旨在处理mock对象的命名空间问题,避免无意中创建错误属性。
  • 😀 在使用mock对象时,如果断言方法的名称错误,'unsafe'特性将触发断言错误,提醒开发者问题。
  • 😀 Python的设计理念中,通过将方法与类分离,避免了命名冲突,这种做法在DataClass中得到了很好的实现。
  • 😀 通过从Python历史中的错误(如NameTuple和mock)中吸取教训,开发者可以更好地设计自己的类生成器和命名空间管理策略。

Q & A

  • 什么是`namedtuple`?

    -`namedtuple`是Python中的一个内建类工厂,用于创建具名元组类。通过给定类名和字段名,它会自动创建一个可以像普通元组一样使用的类,但每个字段都可以通过名字访问。

  • 为什么在`namedtuple`中,一些方法和属性名前加了下划线?

    -这些方法和属性(如`asdict`、`replace`等)前加下划线是为了避免与用户可能定义的字段名称冲突。Python通过在这些方法名前加下划线,创造了一个命名空间,避免了与用户代码的潜在冲突。

  • `namedtuple`和`data class`有何异同?

    -`namedtuple`使用类名和字段名动态生成类,适用于需要快速创建简单数据结构的场景。`data class`则是通过类型注解来定义字段,并提供了一些额外的功能,如默认值和字段验证,通常用于更复杂的类设计。

  • 为什么`data class`比`namedtuple`更好?

    -`data class`通过将方法功能提取到模块级函数,避免了命名空间冲突的问题。而`namedtuple`则将方法放入同一类中,可能导致用户自定义字段名与这些方法冲突。

  • 什么是mock对象?

    -mock对象是一个模拟的对象,通常用于测试中代替实际对象。它允许你定义返回值和行为,而不依赖于真实对象的实现。mock对象的行为是可配置的,可以模拟真实对象的调用和属性。

  • 为什么`mock`对象会导致测试中出现错误?

    -因为`mock`对象允许无限制地访问和创建属性,如果测试代码中有拼写错误,`mock`对象会默默返回另一个`mock`对象,而不会抛出错误。这可能导致测试假通过,未能捕获实际的逻辑问题。

  • Python 3.5中的`unsafe`属性解决了什么问题?

    -Python 3.5引入了`unsafe`属性,以避免在`mock`对象中出现拼写错误导致测试错误通过。该属性会在调用不存在的属性时引发`AssertionError`,从而帮助开发者捕捉潜在的错误。

  • `assert_called_once_with`和`assert_called_with`有什么区别?

    -`assert_called_once_with`用于断言mock对象的某个方法只被调用了一次,并且调用参数符合预期。而`assert_called_with`则用于断言该方法在任意次数调用后,最后一次调用的参数符合预期。

  • 为什么Python中的命名空间设计很重要?

    -命名空间的设计决定了不同部分代码是否会冲突。通过避免将方法和属性直接放入类的命名空间中(如`namedtuple`中的做法),可以减少用户自定义字段与库方法的冲突。

  • 在`mock`对象中,如何避免无意中的命名冲突?

    -可以使用`spec`参数来定义`mock`对象的行为,从而限制它只能模拟指定的接口。这样一来,如果你试图访问未定义的属性或方法,`mock`对象会抛出错误,而不是返回另一个`mock`对象。

Outlines

plate

This section is available to paid users only. Please upgrade to access this part.

Upgrade Now

Mindmap

plate

This section is available to paid users only. Please upgrade to access this part.

Upgrade Now

Keywords

plate

This section is available to paid users only. Please upgrade to access this part.

Upgrade Now

Highlights

plate

This section is available to paid users only. Please upgrade to access this part.

Upgrade Now

Transcripts

plate

This section is available to paid users only. Please upgrade to access this part.

Upgrade Now
Rate This

5.0 / 5 (0 votes)

Related Tags
Python编程命名空间类生成器namedtupledataclass单元测试mock对象编程设计错误处理测试优化开发经验软件工程
Do you need a summary in English?