假设我有以下IronPython脚本:
def Calculate(input):
return input * 1.21
当使用小数从C#调用时,此函数返回一个double:
var python = Python.CreateRuntime();
dynamic engine = python.UseFile("mypythonscript.py")
decimal input = 100m; // input is of type Decimal
// next line throws RuntimeBinderException:
// "cannot implicitly convert double to decimal"
decimal result = engine.Calculate(input);
我似乎有两种选择:
首先,我可以在C#侧进行投射:看起来像是一个禁区,因为我可能会失去精确度。
decimal result = (decimal)engine.Calculate(input);
第二个选项是在python脚本中使用System.Decimal:工作,但稍微污染了脚本......
from System import *
def CalculateVAT(amount):
return amount * Decimal(1.21)
是否有一个简写符号DLR,数字1.21应该被解释为十进制,就像我在C#中使用'1.21m'符号一样?或者有没有其他方法来强制使用十进制而不是double?
答案 0 :(得分:5)
查看python docs:
十进制实例可以用整数,字符串或者构造 元组。从a创建一个Decimal float,首先将其转换为字符串。 这可以作为一个明确的提醒 转换的细节 (包括表示错误)。
不幸的是,你找不到简写符号。即使是python也没有。 “硬编码”十进制的标准方法是将字符串表示传递给十进制构造函数:
from decimal import Decimal
my_decimal = Decimal("1.21")
如果您正在编写重载.net互操作的代码(看起来像你),可能最好立即使用.net Decimal数据类型,就像你自己提出的那样。但请注意,在此示例中,您将浮点数传递给十进制构造函数。如果数字包含更多的小数位,则转换的准确性可能会出现小误差:
from System import *
my_decimal = Decimal(1.21)
所以你最好使用这个构造函数重载:
from System import *
my_decimal = Decimal(121, 0, 0, False, 2)
不是做你想要的最美丽和最短的方式,但在性能和准确性方面是最好的。
答案 1 :(得分:3)
似乎是一种禁忌,因为我可能会失去精确度。
是的,你也可以用另一种方法做到这一点:
Decimal(1.21)
一旦你写了1.21
这是一个浮点数,你甚至在将它传递给Decimal构造函数之前就已经失去了完整的精度。这就是为什么Python的本地Decimal
类必须从字符串初始化,而不是浮点数:
decimal.Decimal('1.21')
.NET的Decimal似乎没有类似的构造函数,但您也许可以使用constituent parts constructor来完成:
System.Decimal(121, 0, 0, False, 2)