社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 中千万不要直接返回 None

数据STUDIO • 1 周前 • 15 次点击  


在 Python 中,处理缺失值时直接返回 None 并不是一个好的做法。作为一个初学者,我曾经也经常这样做,但后来我意识到这会导致代码中出现难以调试的错误,并且需要额外的检查来确保程序的正常运行。

例如,假设我们有一个字典,我们想从中获取某个键的值。如果该键不存在,直接返回 None 可能会导致后续代码出现问题,因为 None 并不包含任何有用的信息,而且可能会引发异常。

例如,如果我像这样从字典中获取数据:

user_data = {"name""Kiran""age": 25}
def get_email(user):
    return user.get("email")  # This will return None if key is missing

e = get_email(user_data)
print(e.upper())  #AttributeError: 'NoneType' object has no attribute 'upper'

如你所见,我们的程序崩溃了。为了避免这种情况,我们必须使用 if e is not None 检查。这有点恼人。

我们应该采用一些不同的方法来解决这个问题。

1. 尝试使用默认值

如果键不存在,返回一个默认值,而不是 None

而不是这样做:

def get_username(user):
    if 'name' in user:
        return user['name']
    return None         # This is bad idea

我们可以这么做

def get_username(user):
    return user.get('name'"Guest")  # It will return a default value
    
    
def get_value(data, key, default="Default Value"):
    return data.get(key, default)

value = get_value(my_dict, 'some_key'"Key not found")
print(value)

这将返回一个默认值(GUEST)。这将确保我们的程序在尝试使用结果时不会中断。如果我们想顺利运行程序,最好使用这种方法。

但如果缺失的数据显示了需要立即关注的问题,我们也可以引发异常。我们应该始终选择适合自己需要的方法。

如果你想使用默认值,那么请确保它们在你的上下文中是有意义的。

2. 如果 None 出现意外,我们可以引发异常

如果键不存在是一个异常情况,可以选择抛出异常。

不要这样做

def get_price(product):
    if 'price' in product:
        return product['price']
    return None           #this is bad approach

我们可以这么做

def get_price(product):
    if 'price' not in product:
        raise ValueError("Product must have a price!")
    return product['price']
    

我们也可以明确地提出错误。这将迫使调用者正确处理这种情况。

例如,调用者可以像这样捕获异常并进行相应处理:

try:
    price = get_price(product)
except ValueError as e:
    print(f"Error: {e}")  # This will handle missing price properly

3.使用 collections.defaultdict

如果你经常需要处理缺失值,可以使用 collections.defaultdict,它会为不存在的键提供一个默认值。

from collections import defaultdict

my_dict = defaultdict(lambda: "Default Value")
my_dict['existing_key'] = "Some Value"

print(my_dict['existing_key'])  # 输出: Some Value
print(my_dict['non_existing_key'])  # 输出: Default Value

4. 使用 Optional 类型提示

如果在某些情况下需要返回 None ,那么至少我们应该使用类型提示来明确说明。

而不是这样做

def find_user(username):
    ...  # Some logic
    return None  # Hidden None return

我们应该这么做

from typing import Optional
def find_user(username: str) -> Optional[dict]:
    ...  # Some logic
    return None  # Explicitly stated as an optional return type

现在,如果任何开发人员阅读了这个函数,他/她就会在开始时知道他们需要在这里明确处理 “None”情况。

这也有助于静态分析工具和集成开发环境提供适当的提示和警告。

5. 使用自定义封装类

我们还可以将返回值封装在一个明确表示缺失值的类中

例如:

class Missing:
    def __bool__(self):
        return False

MISSING = Missing()

def get_email(user):
    return user.get('email', MISSING)

email = get_email({})

if not email:
    print("No email provided")

我们不必依赖 None, 这种方法会让我们清楚地知道何时缺少一个值。

6. 使用result模式

我们可以为可能失败的函数返回一个结构化的结果......而不是返回None。

例如

from typing import NamedTuple, Union
class Result(NamedTuple):
    success: bool
    value: Union[str, None]

def get_country(user) -> Result:
    if 'country' in user:
        return Result(True, user['country'])
    return Result(False, None)

result = get_country({})
if not result.success:
    print("No country found!")

这种模式可以清楚地说明函数是否成功。

只要这样做......而不是返回None......只要使用这种更好的方法。

希望对你有所帮助。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/180224
 
15 次点击