python - Python:无和尝试除外
问题描述
我正在为预算计划制作测试工具。个人购买由 Item 类表示。如果类初始化不正确,我想返回 None。但是,当我运行我的测试工具时,它不会将变量检测为无。为什么测试工具没有将项目检测为无?
def __init__(self, nameItem, costItem):
try:
if costItem < 0.00 or type(nameItem) is not str:
self = None
else:
if len(nameItem) < 1:
self = None
else:
self.name = nameItem
self.cost = round(costItem,2)
if self.name == None or self.cost == None:
self = None
except:
self = None
#Test Case
currentTest = currentTest + 1
print("Test" ,currentTest,":Create invalid item using negative cost.")
try:
testItem = Item("Coffee",-1.00)
if testItem is None:
print("Made None value when given incorrect data:TEST PASSED")
passTests = passTests + 1
else:
raise TypeError
except TypeError:
print("Error when creating item, created item instead of detecing error:TEST FAILED")
failedTests.insert(failedCount,currentTest)
failedCount = failedCount + 1
except:
print("Error when conducting test:TEST FAILED")
failedTests.insert(failedCount,currentTest)
failedCount = failedCount + 1
解决方案
内部__init__()
(或任何类方法)self
是一个局部变量,绑定到调用此方法的对象。分配给它只会影响该局部变量的绑定,它不会更改对存在于方法之外的对象的实际引用。
当你到达时__init__
,对象已经被分配了——你也许可以用一些“诡计”来扭转它,但我不确定这是否是一个好主意,即使可能。
处理初始化问题的正常 (a)方法是简单地抛出一个异常,该异常可以被捕获以适当地重新绑定变量(或根据需要执行其他操作):
try:
item = className()
except:
item = None
您甚至可以提供一个辅助函数来为您完成繁重的工作,因此构建仍然只需要一行,例如:
class ClassName:
def __init__(self, makeFail):
if makeFail: raise Exception("ouch")
def tryMake(cls, *args):
try:
return cls(*args)
except:
return None
print(tryMake(ClassName, False)) # equiv: print(ClassName(False))
print(tryMake(ClassName, True))
从输出中可以看出,它将失败的构造转换为None
:
<__main__.ClassName object at 0x7f7ed1e38c70>
None
但是,如果您真的想执行您建议的操作但不想捕获异常或通过辅助函数重新绑定,则存在另一种可能性。
之前调用了另一个魔术函数,它能够返回不同的类型。只有当它返回请求的类型时,Python 才会调用它。__new__
__init__
__init__
因此,您可以定义__new__
调用来检查价格并在类型无效时拒绝实例化类型,如下面的示例代码所示:
class Item:
def __new__(cls, item, price):
if price < 0:
return None
return super(Item, cls).__new__(cls)
def __init__(self, item, price):
self.item = item
self.price = price
def __str__(self):
return f"({self.item}, {self.price})"
print(Item("Coffee", 4.50))
print(Item("Tea", -1))
print(Item("Biscuit", 2.75))
这似乎是你想要的输出:
(Coffee, 4.5)
None
(Biscuit, 2.75)
现在这可能不是我会做的事情,而是宁愿抛出异常__init__()
并让调用者以他们选择的任何方式处理它(如果需要,包括使用辅助函数)。
(a)定义为:
正常 (n) - 不会让经验丰富的 Python 开发人员质疑您的理智 :-)
推荐阅读
- service - symfony 5 服务问题 => 不在对象上下文中使用 $this
- python - Python - 国旗和肤色表情符号无法正确显示
- android - 无法在颤振中创建应用程序目录
- java - 使用 Java 使用 selenium 在电子应用程序上切换句柄
- magento2 - Magento 2.4.1 将 vat_id 添加到新订单确认模板
- react-native - 如何在 react-native 中映射来自 redux 的数据
- webgl - 当结构包含数组时从结构数组存储结构会导致编译错误
- html - Bootstrap 响应式按钮大小
- c - C:放置和使用malloc
- django - 如何为 Django 应用程序将 Amazon Elastic Beanstalk Linux 1 升级到 Linux 2