【问题标题】:Assert on all outputs - is that a good practice?断言所有输出 - 这是一个好习惯吗?
【发布时间】:2021-08-31 18:52:37
【问题描述】:

我在所有输出上都使用断言,这是一个好习惯吗?这段代码也干净易读吗?谢谢!

#!/usr/bin/env python

import pyodbc
import secret as credentials

class DatabaseManager:
    def __init__(self):
        self.database_user_name = credentials.Secret.mssql["database_username"]
        self.database_password = credentials.Secret.mssql["database_password"]
        self.database_server_name = credentials.Secret.mssql["database_server"]
        self.database_name = credentials.Secret.mssql["database_name"]
        self.database_string = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=' \
                               + self.database_server_name + ';DATABASE=' \
                               + self.database_name + ';UID=' \
                               + self.database_user_name + ';PWD=' \
                               + self.database_password \
                               + ';Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'
        self.database_connection = pyodbc.connect(self.database_string)


class AccountManager:
    def __init__(self, account_email, account_name):
        self.account_email = account_email
        self.account_name = account_name

    def get_account_by_email(self):
        db_init = DatabaseManager()
        db_cursor = db_init.database_connection.cursor()
        db_cursor.execute("""  SELECT [account_email] FROM  [dbo].[account] 
                               WHERE account_email = ? """, self.account_email)
        row: object = db_cursor.fetchone()

        # verify and return
        assert isinstance(row, object)
        print(row)

    def get_account_by_name(self):
        db_init = DatabaseManager()
        db_cursor = db_init.database_connection.cursor()
        db_cursor.execute("""   SELECT [account_name] FROM  [dbo].[account] 
                                WHERE account_name = ? """, self.account_name)
        row: object = db_cursor.fetchone()

        # verify and return
        assert isinstance(row, object)
        print(row)


class ContractManager:
    def __init__(self):
        pass

【问题讨论】:

  • isinstance(anything, object) 始终为 True,因此您的断言毫无用处。
  • 另请注意,您不会从这些函数返回任何内容。您正在检查您刚刚打印出来的对象的类型。
  • 我正在打印它,因为我正在测试它——它从数据库返回一个值。从数据库返回的值为 str 将包括 int。

标签: python coding-style


【解决方案1】:

在 Python 中,一切都是对象。您拥有的 assert 语句将捕获布尔值、整数、列表等所有内容。

您说过有时会从数据库中返回一个整数。如果这是一个问题,您应该引发错误而不是使用断言语句。

断言应用作现场执行的快速测试,以验证一切是否符合您对数据外观的期望,然后再继续进行。请记住,断言语句在生产模式下被禁用。您只想使用它们来验证您认为永远不可能真实的条件,但就像可以让您放心的快速理智检查一样,您无论如何都要进行检查。如果有某种方式可以使条件为真,则应该使用异常来代替,以便在生产环境中引发实际错误。

另外,请注意type hints 可以涵盖许多过去使用的断言语句。

【讨论】:

    【解决方案2】:

    在您的情况下,对对象实例使用 assert 语句通常不好,因为它始终是 True

    assert 对检查inputsdata-type 非常有用。

    示例:

    def add_num(num1):
        assert isinstance(num1, int), "the num1 should be of type 'int'."
        return num1+3
    

    或者,当您将type-hint 用于您传递到classobject 的相应arguments 时,代码可以变得更好。

    示例:

    def add_num(num1: int):
        return num1+3
    

    【讨论】:

    • 这似乎无法回答问题。
    • 但我也可以这样做: row: object = db_cursor.fetchone() 然后断言 isinstance(row, object) 来检查返回类型是我期望的吗?对?对象、str、int 等。
    • 是的,如果您不确定从数据库中获取的类型,我还建议使用消息部分通知用户,以防断言上升。即断言 ,
    • 谢谢,Danke,Gracias。
    猜你喜欢
    • 2010-09-11
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2019-09-26
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多