Skip to main content

Python Money Class

Project description

Money class with optional CLDR-backed locale-aware formatting and an extensible currency exchange solution.

All code examples use Python 3.x.

Contents

Installation

This package is compatible with Python 2.7, 3.3, 3.4, but there are important Differences between Python versions.

pip install money

For locale-aware formatting, also install Babel:

pip install babel

Basic usage

>>> from money import Money
>>> m = Money(amount='2.22', currency='EUR')
>>> m
EUR 2.22

amount can be any valid value for decimal.Decimal(value) and currency should be a three-letter currency code. You can perform most arithmetic operations between money objects and integers or decimals.

>>> from money import Money
>>> m = Money('2.22', 'EUR')
>>> m / 2
EUR 1.11
>>> m + Money('7.77', 'EUR')
EUR 9.99

Arithmetic operations with floats are not directly supported. If you need to operate with floats, you must first convert the float to a Decimal, or the Money object to a float (i.e. float(m)). Please be aware of the issues and limitations of floating point arithmetics.

Formatting

Money objects are printed by default with en_US formatting and the currency code.

>>> m = Money('1234.567', 'EUR')
>>> str(m)
'EUR 1,234.57'

Use format(locale=DEFAULT_LC_NUMERIC, pattern=None) for locale-aware formatting with currency expansion. format() emulates babel.numbers.format_currency(), and requires Babel to be installed:

>>> m = Money('1234.567', 'USD')
>>> m.format('en_US')
'$1,234.57'
>>> m.format('es_ES')
'1.234,57\xa0US$'

The character \xa0 is an unicode non-breaking space (chicken-good). If no locale is passed, Babel will use your system’s locale. You can also provide a specific pattern to format():

>>> m = Money('-1234.567', 'USD')
>>> # Regular US format:
>>> m.format('en_US', '¤#,##0.00')
'-$1,234.57'
>>> # Custom negative format:
>>> m.format('en_US', '¤#,##0.00;<¤#,##0.00>')
'<$1,234.57>'
>>> # Round, Spanish format, full currency name:
>>> m.format('es_ES', '0 ¤¤¤')
'-1235 dólares estadounidenses'

Learn more about the formatting syntax:.

Currency exchange

Currency exchange works by “installing” a backend class that implements the abstract base class (abc) money.exchange.BackendBase. Its API is exposed through money.xrates, along with setup functions xrates.install(pythonpath), xrates.uninstall(), and xrates.backend_name.

A simple proof-of-concept backend money.exchange.SimpleBackend is included:

from decimal import Decimal
from money import Money, xrates

xrates.install('money.exchange.SimpleBackend')
xrates.base = 'USD'
xrates.setrate('AAA', Decimal('2'))
xrates.setrate('BBB', Decimal('8'))

a = Money(1, 'AAA')
b = Money(1, 'BBB')

assert a.to('BBB') == Money('4', 'BBB')
assert b.to('AAA') == Money('0.25', 'AAA')
assert a + b.to('AAA') == Money('1.25', 'AAA')

You can use a subclass of Money, XMoney if you prefer automatic conversion between different currencies on binary operations. The currency of the leftmost object has priority.

from money import XMoney

# Register backend and rates as above...

a = XMoney(1, 'AAA')
b = XMoney(1, 'BBB')

assert a + b == XMoney('1.25', 'AAA')

Differences between Python versions

Expression

Python 2.x

Python 3.x

round(Money('2.5', 'EUR'))

Returns 3.0, a float rounded amount away from zero.

Returns EUR 2, a Money object with rounded amount to the nearest even.

Design decisions

There are several design decisions in money that differ from currently available money class implementations:

Localization

Do not keep any kind of locale conventions database inside this package. Locale conventions are extensive and change over time; keeping track of them is a project of its own. There is already such a project and database (the Unicode Common Locale Data Repository), and an excellent python API for it: Babel.

Currency

There is no need for a currency class. A currency is fully identified by its ISO 4217 code, and localization or exchange rates data are expected to be centralized as databases/services because of their changing nature.

Also:

  • Modulo operator (%): do not override to mean “percentage”.

  • Numeric type: you can mix numbers and money in binary operations, and objects evaluate to False if their amount is zero.

  • Global default currency: subclassing is a safer solution.

Contributions

Contributions are welcome. You can use the regular github mechanisms.

To be forward-compatible, and given the small size of the package, Python 2.7 is supported in a different source “branch” at src-py2.

To test your changes you will need tox and python 2.7, 3.3, and 3.4. Simply cd to the package root (by setup.py) and run tox.

License

money is released under the MIT license, which can be found in the file LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

money-1.2.2.tar.gz (16.7 kB view details)

Uploaded Source

File details

Details for the file money-1.2.2.tar.gz.

File metadata

  • Download URL: money-1.2.2.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for money-1.2.2.tar.gz
Algorithm Hash digest
SHA256 c8619a9a40a317cb8a9c7af9951d56452b75d1a41834994502171c1935dbe99d
MD5 c8c44fa7c469a91a5bf33e5b4f4ac197
BLAKE2b-256 71d4c6994f3b91e9278036bdef7866d0c54c3c8c6fa25ab75d599b3ba966069f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page