You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何简化Python类初始化方法中断言语句的多个or判断逻辑?

Cleaner alternative to multiple or operators in Python class init assertions?

Question

I've written the __init__ method for a Python Weapon class, using multiple or operators to assert parameter validity:

class weapon:
    def __init__(self, name: str, weapontype : str, range : str, material : str, price : float, quantity : int):
        assert weapontype == "bladed" or weapontype == "blunt" or weapontype == "polearm" or weapontype == "Ranged", f"{weapontype} is not a valid weapontype"
        assert range == "close range" or range == "medium range" or range == "long range", f"{range} is not a valid range"
        assert material == "metal" or material == "wood", f"{material} is not a valid material type"
        self.name = name
        self.weapontype = weapontype
        self.range = range
        self.material = material
        self.price = price
        self.quantity = quantity

Is there a cleaner way to replace these or operators? I've looked up relevant information but haven't found a solution.

Answer

Absolutely! Those chained or checks can get messy and hard to maintain as your valid options grow—here are two cleaner, more scalable approaches:

1. Use in with a set of valid values

This is the simplest fix: define your valid options as a set (for O(1) lookup speed) and check if the input value is in that set. It’s concise, easy to update, and you can even improve error messages to list valid options for better debugging.

class Weapon:
    def __init__(self, name: str, weapontype: str, range: str, material: str, price: float, quantity: int):
        # Define valid options as sets (faster lookups than lists)
        VALID_WEAPON_TYPES = {"bladed", "blunt", "polearm", "Ranged"}
        VALID_RANGES = {"close range", "medium range", "long range"}
        VALID_MATERIALS = {"metal", "wood"}
        
        assert weapontype in VALID_WEAPON_TYPES, f"{weapontype} is not a valid weapontype. Valid options: {', '.join(VALID_WEAPON_TYPES)}"
        assert range in VALID_RANGES, f"{range} is not a valid range. Valid options: {', '.join(VALID_RANGES)}"
        assert material in VALID_MATERIALS, f"{material} is not a valid material type. Valid options: {', '.join(VALID_MATERIALS)}"
        
        self.name = name
        self.weapontype = weapontype
        self.range = range
        self.material = material
        self.price = price
        self.quantity = quantity

2. Use enum.Enum for type safety

If you want stronger type enforcement (to avoid accidental typos like "blade" instead of "bladed"), using Python’s Enum class is a great choice. It encapsulates valid values, gives you IDE autocompletion, and makes your code more self-documenting.

from enum import Enum

# Define enums for each category of valid values
class WeaponType(Enum):
    BLADED = "bladed"
    BLUNT = "blunt"
    POLEARM = "polearm"
    RANGED = "Ranged"

class WeaponRange(Enum):
    CLOSE = "close range"
    MEDIUM = "medium range"
    LONG = "long range"

class Material(Enum):
    METAL = "metal"
    WOOD = "wood"

class Weapon:
    def __init__(self, name: str, weapontype: WeaponType, range: WeaponRange, material: Material, price: float, quantity: int):
        # Optional: Handle cases where someone might pass a string instead of the Enum
        if isinstance(weapontype, str):
            weapontype = WeaponType(weapontype)
        if isinstance(range, str):
            range = WeaponRange(range)
        if isinstance(material, str):
            material = Material(material)
        
        # Store either the Enum instance or its string value (your choice)
        self.name = name
        self.weapontype = weapontype.value
        self.range = range.value
        self.material = material.value
        self.price = price
        self.quantity = quantity

With enums, you get runtime checks that the input is valid, and you don’t need explicit assertions if you enforce the type hints (though the string fallback is helpful for flexibility).

Which to choose?

  • Use the set + in approach for quick, simple validation where you don’t need strict type enforcement.
  • Use Enums if you want to enforce valid values throughout your codebase, reduce typos, and make your code more readable.

内容的提问来源于stack exchange,提问作者user19803102

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:52:41