人性化和灵活的货币金额工作包

stockholm的Python项目详细描述


stockholm

这为Python3带来了一个功能齐全的Money类&{}。

{1}$ pypiMade with PythonType hinted - mypy validatedMIT LicenseCode coverage

库,用于格式化货币金额并执行算术和比较操作。还支持货币处理、交换和网络传输结构生成以及解析。

一种最新的、对人类友好的、灵活的发展方式,任何一种货币都可以。不再需要处理float或者必须考虑子单元中的值。在

基本上是python3.x的高端Money类。这是一个供fintech公司、web商家或订阅服务的后端和前端API编码人员使用的库。它非常适合于计算数量,同时保持很高的精度或为传输层生成输出,并且有一种健壮而简单的方法来导入/导出GraphQLJSON和/或{em1}$Protocol Buffers等中的值

fromstockholmimportMoney

一种简单但功能强大的货币编码方式。


from stockholm import Money

stockholm.Money对象与intfloatDecimal、其他Money对象以及string一起具有完整的算术支持。stockholm.Money对象还支持复杂的字符串格式化功能,以便于调试和干净的编码模式。在

from stockholm import Currency

在创建新的Money对象时,可以使用stockholm.Currency元类生成的货币来指定货币对货币的金额,或者只需将货币代码指定为字符串(例如"SEK"或{})。在

使用stockholm.Currency元类的货币可以包含其他选项,例如字符串输出中的默认小数位数。请注意,幕后金额实际上使用与Decimal值相同的精度和后端,并且可以与这些值互换,因此它们比浮点值更精确地进行计算。在

{cd20>安装

像安装其他Python包一样,使用pippoetrypipenv或您最喜欢的工具。在

^{pr2}$

或安装协议缓冲区支持,自动包括protobuf包。在

$ pip install stockholm[protobuf]

文档快捷方式:

用法和示例

算法-完全支持

对不同类型的完全算术支持,由Decimal支持,用于处理舍入错误,同时还保持货币金额的完全货币意识。

fromstockholmimportMoneymoney=Money("4711.50",currency="SEK")print(money)# 4711.50 SEKoutput=(money+100)*3+Money(50)print(output)# 14484.50 SEKprint(output/5)# 2896.90 SEKprint(round(output/3,4))# 4828.1667 SEKprint(round(output/3,1))# 4828.20 SEK# Note that you can only do arithmetics on two monetary amounts which shares the# same currency, monetary amounts that doesn't hold a currency at all or an# operation between a currency aware monetary object and a value that doesn't hold# data about a currency.# Look at the following examples of completely legit operations.Money("100 SEK")+Money("50 SEK")# <stockholm.Money: "150.00 SEK">Money("100 EUR")*20+5-3.5# <stockholm.Money: "2001.50 EUR">Money("100 USD")-Money("10")# <stockholm.Money: "90.00 USD">Money("100")-Money("50")+20# <stockholm.Money: "70.00">Money("100")+Money(2,currency="GBP")# <stockholm.Money: "102.00 GBP">Money("100",currency="EUR")+Money("10 EUR")-50+"20.51 EUR"# <stockholm.Money: "80.51 EUR"># And here's operations that tries to use two amounts with different currencies.Money("100",currency="SEK")+Money("10 EUR")# ! This results in a stockholm.exceptions.CurrencyMismatchError exceptionMoney(1)+Money("55 EUR")+Money(10,currency="EUR").to_currency("USD")# ! This results in a stockholm.exceptions.CurrencyMismatchError exception# Also note that you cannot multiply two currency aware monetary amounts by each# other, for example say "5 EUR" * "5 EUR", that in that case would've resulted# in "25 EUR EUR". A monetary amount can only hold one instance of currency.Money("5 EUR")*Money("5 EUR")# ! This results in a stockholm.exceptions.InvalidOperandError exception

格式化/高级字符串格式

高级字符串格式化功能。

fromstockholmimportMoneyjpy_money=Money(1352953,"JPY")exchange_rate=Money("0.08861326")sek_money=Money(jpy_money*exchange_rate,"SEK")print(f"I have {jpy_money:,.0m} which equals around {sek_money:,.2m}")print(f"The exchange rate is {exchange_rate} ({jpy_money:c} -> {sek_money:c})")# I have 1,352,953 JPY which equals around 119,889.58 SEK# The exchange rate is 0.08861326 (JPY -> SEK)# Standard string format uses default min decimals up to 9 decimalsprint(f"{sek_money}")# 119889.57595678 SEK# Format type "f" works the same way as formatting a float or Decimalprint(f"{jpy_money:.0f}")# 1352953print(f"{sek_money:.2f}")# 119889.58print(f"{sek_money:.1f}")# 119889.6print(f"{sek_money:.0f}")# 119890# Format type "m" works as "f" but includes the currency in string outputprint(f"{sek_money:.2m}")# 119889.57 SEKprint(f"{sek_money:.4m}")# 119889.5760 SEKprint(f"{sek_money:+,.4m}")# +119,889.5760 SEK# An uppercase "M" puts the currency ticker in front of the amountprint(f"{sek_money:.4M}")# SEK 119889.5760# Format type "c" will just output the currency used in the monetary amountprint(f"{sek_money:c}")# SEK
{a14{a1}实现的所有十进制数^{1}所有正确数字的输出^{1}见{1}使用完整的数字。
fromstockholmimportCurrency,Money,get_currencyfromstockholm.currencyimportJPY,SEK,EUR,IQD,USDCoin,Bitcoin# Most currencies has a minimum default digits set to 2 in stringsprint(Money(4711,SEK))# 4711.00 SEKprint(Money(4711,EUR))# 4711.00 EUR# The stockholm.currency.JPY has a minimum default digits set to 0print(Money(4711,JPY))# 4711 JPY# Some currencies even has a minimum default of 3 or 4 digitsprint(Money(4711,IQD))# 4711.000 IQD# Some complex non ISO 4217 currencies, assets or tokens may define# their own ticker, for example a "USD Coin" uses the ticker "USDC"print(Money(4711,USDCoin))# 4711.00 USDCprint(Money(4711,Bitcoin))# 4711.00 BTC# You can also use the shorthand stockholm.Currency object which# holds all ISO 4217 three character codes as objects.print(Money(1338,Currency.JPY))# 1338 JPY# or call the get_currency functionprint(Money(1338,get_currency("JPY")))# 1338 JPY

以灵活变量输入数据类型

使用多种不同的输入数据类型和方法为货币量赋值的灵活方法。

fromdecimalimportDecimalfromstockholmimportMoneyMoney(100,currency="EUR")# <stockholm.Money: "100.00 EUR">Money("1338 USD")# <stockholm.Money: "1338.00 USD">Money("0.5")# <stockholm.Money: "0.50">amount=Decimal(5000)/3Money(amount,currency="XDR")# <stockholm.Money: "1666.666666667 XDR">money=Money("0.30285471")Money(money,currency="BTC")# <stockholm.Money: "0.30285471 BTC"># Reading values as "sub units" (multiplied by 100) can come in handy when parsing# some older types of banking files, where all values are presented as strings in# cents / ören / etc.cents_as_str="471100"money=Money(cents_as_str,currency="USD",from_sub_units=True)# <stockholm.Money: "4711.00 USD">money.sub_units# Decimal('471100')

列出算术-列表中的货币金额摘要

从列表中添加几个货币金额。

fromstockholmimportMoneyamounts=[Money(1),Money("1.50"),Money("1000"),]# Use Money.sum to deal with complex values of different data typesMoney.sum(amounts)# <stockholm.Money: "1002.50"># Built-in sum may also be used (if only working with monetary amounts)sum(amounts)# <stockholm.Money: "1002.50">

其他传输介质的转换(例如协议缓冲区或JSON)

很容易拆分为units和{},以便在网络介质中进行传输,例如在使用协议缓冲区时使用^{} protobuf definition
fromstockholmimportMoneymoney=Money("22583.75382","SEK")money.units,money.nanos,money.currency_code# (22583, 753820000, 'SEK')# or vice versaMoney(units=22583,nanos=753820000,currency="SEK")# <stockholm.Money: "22583.75382 SEK">
Monetary amounts也可以导出到dict,也可以使用dict值输入创建,这对于在JSON中传输货币值非常有用。
fromstockholmimportMoneymoney=Money("4711.75","SEK")dict(money)# or by using: money.asdict()# {'value': '4711.75 SEK', 'units': 4711, 'nanos': 750000000, 'currency_code': 'SEK'}# A monetary amount object can be created from a dict either by passing dict directly# to the Money() constructor or by using Money.from_dict(dict_input). Not all values# needs to be available in the input dict, either "units", "nanos", "value" or "amount"# should be specified or any combination of them, as long as values would result in the# same output monetary value.money=Money.from_dict({"value":"4711.75 SEK","units":4711,"nanos":750000000,"currency_code":"SEK"})# <stockholm.Money: "4711.75 SEK">
使用协议缓冲区在网络上传输货币金额。
fromstockholmimportMoney# By default we're utilizing Google's protobuf message called google.type.Money, however# the protobuf class can be overriden with your own if using similar keys and value types.# https://github.com/googleapis/googleapis/blob/master/google/type/money.protomoney=Money("4711.75","SEK")money.as_protobuf()# This will produce a protobuf object which by default holds values for units, nanos and# currency_code as per the google.type.Money protobuf message definition.# Use money.as_protobuf(proto_class=YourProtoClass) if you're using custom messages that# are not of Google's proto message type.## To get the exact byte output produced from the proto class, call their# SerailizeToString() function.money.as_protobuf().SerializeToString()# b'\n\x03SEK\x10\xe7$\x18\x80\xaf\xd0\xe5\x02'# Of course we can also instantiate a monetary amount object by passing a proto message,# either by using the already parsed proto object, or by passing the byte data directly.# If no proto_class keyword argument is specified, we'll once again default to# google.type.Money.money=Money.from_protobuf(b'\n\x03SEK\x10\xe7$\x18\x80\xaf\xd0\xe5\x02')# <stockholm.Money: "4711.75 SEK"># In another example we'll build the message just before hand to be extra descriptive# of what's happening. The stockholm.MoneyProtoMessage class is a compiled Python# representation of the google.type.Money protobuf message definition. You can also use# your own custom class.fromstockholmimportMoneyProtoMessagemessage=MoneyProtoMessage()message.units=2549message.nanos=990000000# If you're using custom classes that aren't generated from google.type.Money, then pass# your generated class as the proto_class keyword argument. In this example, it's not# actually needed, since MoneyProtoMessage is built from google.type.Money definitions.money=Money.from_protobuf(message,proto_class=MoneyProtoMessage)# <stockholm.Money: "2549.99">message.SerializeToString()# b'\x10\xf5\x13\x18\x80\xe7\x88\xd8\x03'# Usually the byte data may already be parsed from your proto class into your# proto objects, and if you're using google.type.Money in your messages you could# pass in the object without any additional proto_class keyword.## In the following example we have a message that contains a field on position 1# named "remaining_sum", which in turn holds a google.type.Money value.## Let's say the message holds the following as a parsed proto object:# remaining_sum {#  currency_code: "USD"#  units: 42# }## It's binary representation is b'\n\x07\n\x03USD\x10*'.# And the binary representation of message.remaining_sum is b'\n\x03USD\x10*'.## By passing the monetary part of the message (in this case, the field remaining_sum)# we can immediately create a monetary amount object which is currency aware.money=Money.from_protobuf(message.remaining_sum)# <stockholm.Money: "42.00 USD">## Of course this newly instantiated montary amount object can be accessed in many# different ways, can use arithmetics like normally, etc.money.amount# Decimal('42.000000000')money.units# 42money.nanos# 0money.currency# "USD"money+10# <stockholm.Money: "52.00 USD">money*31-20+Money("0.50")# <stockholm.Money: "1282.50 USD">
以JSON形式读取或输出货币金额
fromstockholmimportMoney# Outputting key-values as a dict or JSON string. For example great when sending monetary# amounts over GraphQL or internal API:s.money=Money(5767.50,currency="EUR")# <stockholm.Money: "5767.50 EUR">## If no keys keyword argument is specified the default keys will be used, which is# value, units, nanos and currency_code.money.as_json()# '{"value": "5767.50 EUR", "units": 5767, "nanos": 500000000, "currency_code": "EUR"}'## Besides value, units, nanos and currency_code, the other keys that can be specified# are amount and currency (converted to str and equivalent to currency_code in this# context).money.as_json(keys=("amount","currency_code"))# '{"amount": "5767.500000000", "currency_code": "EUR"}'# It's also possible directly parse a monetary amount from its incoming JSON stringMoney.from_json('{"value": "5767.50 EUR", "units": 5767, "nanos": 500000000}')# <stockholm.Money: "5767.50 EUR">Money.from_json('{"amount": "5767.500000000", "currency_code": "EUR"}')# <stockholm.Money: "5767.50 EUR">

货币对象的参数

fromstockholmimportCurrency,Money# This is our monetary object, instantiated as 59112.50 EUR using the# currency object stockholm.Currency.EUR, which among other things holds data# regarding how many decimal digits should normally be printed. A monetary amount# in EUR is usually demoninated with two decimal digits.money=Money("59112.50",currency=Currency.EUR)# <stockholm.Money: "59112.50 EUR">money.amount# Decimal('59112.50')# Type: decimal.Decimalmoney.value# '59112.50 EUR'# Type: stringmoney.units# 59112# Type: integermoney.nanos# 500000000# Type: integermoney.currency_code# 'EUR'# Type: Either: A string or Nonemoney.currency# <stockholm.Currency: "EUR"># Type: Either: a currency object, a string (equivalent to currency_code) or Nonemoney.sub_units# Decimal('5911250')# Type: decimal.Decimalmoney.asdict()# {'value': '59112.50 EUR', 'units': 59112, 'nanos': 500000000, 'currency_code': 'EUR'}# Type: dictmoney.as_string()# or: str(money)# '59112.50 EUR'# Type: stringmoney.as_int()# or: int(money)# 59112# Type: integermoney.as_float()# or: float(money)# 59112.5# Type: float# Note that using floats may cause you to lose precision. Floats are strongly discouraged.money.is_signed()# False# Type: booleanmoney.is_zero()# False# Type: booleanmoney.to_integral()# <stockholm.Money: "59113.00 EUR"># Type: stockholm.Moneymoney.amount_as_string(min_decimals=4,max_decimals=7)# 59112.5000# Type: stringmoney.amount_as_string(min_decimals=0)# 59112.5# Type: stringmoney.amount_as_string(max_decimals=0)# 59113# Type: stringmoney.to_currency(currency="SEK")# <stockholm.Money: "59113.50 SEK"># Type: stockholm.Moneymoney.as_json()# '{"value": "59112.50 EUR", "units": 59112, "nanos": 500000000, "currency_code": "EUR"}'# Type: stringmoney.as_json(keys=("amount","currency"))# '{"amount": "59112.50", "currency": "EUR"}'# Type: stringmoney.as_protobuf()# currency_code: "EUR"# units: 59112# nanos: 500000000# Type: stockholm.proto.money_pb2.Money, generated from proto definitions at# https://github.com/googleapis/googleapis/blob/master/google/type/money.protomoney.as_protobuf(proto_class=CustomMoneyProtoMessage)# Type: An instance of CustomMoneyProtoMessage populated with the properties of money

致谢

灵感来自https://github.com/carlospalol/money和{a16}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java的单元测试测试用例库。util。列出实现   java通过超类进行序列化/反序列化   java Android获取设备语言ISO字符串   java如何打开广告的行动。移动   Eclipse IDE for(嵌入式C/C++)开发者202012:经典的深色主题深黑色背景和菜单中的文本   java使用不同的内容动态创建TableView(JavaFX)   java JAXB将多个同名节点解组   java ClassDefNotFoundException,即使类由类加载器加载(服务器上安装了多个应用程序)   java有没有办法关闭在后端生成的MqttClient线程?   html如何在网站上的java小程序中包含图像?   java无法访问已分配给超类引用的子类实例变量   java在TableViewer中双击打开对话框   列出如何创建ListNode。JAVA   java如何从文本中输出的数组中放入随机图像