字符串在货币、日期、精度的处理

发布时间 2023-07-01 10:06:08作者: Allen_Hao

1. 区域设置--locale模块的setlocale函数

区域设置是一个标识特定地理、文化和语言的系统参数。它影响如日期和时间格式、货币和数字格式以及其他地域相关的操作。

在 Python 中,使用 locale.setlocale() 函数可以设置区域设置来适应不同的地区和语言要求。

该函数的语法为:

locale.setlocale(category, locale)
  • category:设置的分类,可以是 locale.LC_ALL(设置所有的分类),或者是其他分类,如 locale.LC_COLLATE(用于字符串排序比较)、locale.LC_CTYPE(用于字符分类和转换)等。
  • locale:所设置的地区和语言的标识符。标识符通常由语言代码和地区代码组成,用下划线分隔,例如 'en_US.UTF-8' 表示英文(美国)。

注意,locale.setlocale() 的行为会受到操作系统的支持程度的限制,因此在不同的操作系统上可能会有不同的表现。需要确保所设置的区域设置在操作系统中是有效的。

eg:locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') 是 Python 中用来设置当前系统的区域设置(locale)的函数调用。它将本地化环境设置为使用英文(美国)并且字符编码为 UTF-8。

2. 货币

# 1. 表示货币:

# 使用 locale 模块来设置地区和货币格式,然后使用 locale.currency() 函数来格式化货币。
import locale

# 获取当前默认的区域设置
# default_locale = locale.getdefaultlocale()  # 过时方法
default_locale = locale.getlocale()
print(default_locale) # ('Chinese (Simplified)_China', '936')

import sys

# 获取当前的编码
encoding = sys.getdefaultencoding()
print(encoding)  # utf-8 获取当前的编码

# 设置地区和货币格式
# locale.setlocale(locale.LC_ALL, 'Chinese.UTF-8')  # 中文
# 设置区域为英文
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

# 格式化货币
amount = 1234.56
currency = locale.currency(amount)
print(currency) # 英文输出 "$1,234.56",中文是:¥1234.56

 

3. 日期

1 # 2. 日期:使用 datetime 模块中的datetime来处理日期和时间,并使用 strftime() 方法来格式化日期
2 from datetime import datetime
3 
4 # 获取当前日期和时间
5 now = datetime.now()
6 
7 # 格式化日期
8 formatted_date = now.strftime("%Y-%m-%d")
9 print(formatted_date)  # 2023-07-01
formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")  
print(formatted_date) # 2023-07-01 09:18:44

4. 数字精度

4.1  round() 函数

内置函数,用于将浮点数四舍五入到指定的精度

 1 value = 3.7
 2 # 将数字四舍五入到整数
 3 rounded_value = round(value)
 4 print(rounded_value)  # 输出: 4
 5 
 6 
 7 value = 3.14159
 8 #  数字保留2个小数位,四舍五入看小数的第3位
 9 rounded_value = round(value, 2)
10 print(rounded_value)  # 输出 3.14
11 value = 3.145
12 rounded_value = round(value, 2)
13 print(rounded_value)  # 输出 3.15

4.2 math 模块

 1 '''
 2 math 模块提供了三个常用的数学函数用于处理舍入操作:ceil()、floor() 和 trunc()。
 3 
 4 ceil(x) 函数返回大于或等于 x 的最小整数。
 5 floor(x) 函数返回小于或等于 x 的最大整数。
 6 trunc(x) 函数返回 x 的整数部分,忽略小数部分
 7 '''
 8 import math
 9 '''
10 ceil() 函数:
11 
12 ceil(x) 函数返回大于或等于 x 的最小整数。如果 x 已经是整数,则返回 x 本身。
13 最佳实践:使用 ceil() 函数来向上取整,即获取大于或等于给定数值的最小整数。
14 '''
15 value = 3.14159
16 rounded_value = math.ceil(value)
17 print(rounded_value) # 输出 4
18 
19 '''
20 floor() 函数:
21 
22 floor(x) 函数返回小于或等于 x 的最大整数。如果 x 已经是整数,则返回 x 本身。
23 最佳实践:使用 floor() 函数来向下取整,即获取小于或等于给定数值的最大整数。
24 '''
25 import math
26 
27 x = 3.9
28 result = math.floor(x)
29 print(result)  # 输出: 3
30 
31 '''
32 trunc() 函数:
33 
34 trunc(x) 函数返回 x 的整数部分,忽略小数部分。如果 x 是正数,则返回不大于 x 的最大整数;如果 x 是负数,则返回不小于 x 的最小整数。
35 最佳实践:使用 trunc() 函数进行截断操作,即将数字的小数部分去掉,保留整数部分。
36 '''
37 import math
38 
39 x = 3.9
40 result = math.trunc(x)
41 print(result)  # 输出: 3
42 
43 x = -3.9
44 result = math.trunc(x)
45 print(result)  # 输出: -3

4.3  decimal 模块

decimal 模块提供了更精确的十进制运算,用于处理浮点数精度问题。以下是使用 decimal 模块的最佳实践和示例:

1. 导入 decimal 模块并设置精度

2. 创建 Decimal 对象

3. 进行精确的十进制运算

4. 格式化 Decimal 对象为字符串

 1 # 1. 导入 decimal 模块并设置精度:
 2 from decimal import Decimal, getcontext
 3 
 4 # 设置精度为2位小数
 5 getcontext().prec = 2
 6 
 7 # 2. 创建 Decimal 对象:
 8 # 使用字符串创建 Decimal 对象
 9 decimal_number = Decimal('3.14159')
10 
11 # 使用浮点数创建 Decimal 对象
12 decimal_number = Decimal(3.14159)
13 
14 # 3. 进行精确的十进制运算:
15 # 加法
16 result = Decimal('2.3') + Decimal('4.5')
17 print(result)  # 输出: 6.8
18 
19 # 减法
20 result = Decimal('5.6') - Decimal('2.1')
21 print(result)  # 输出: 3.5
22 
23 
24 result = Decimal('2.5') * Decimal('1.5')
25 print(result)  # 输出: 3.8
26 # 除法
27 result = Decimal('5.6') / Decimal('2.0')
28 print(result)  # 输出: 2.8
29 
30 # 幂运算
31 result = Decimal('2.0') ** Decimal('3.0')
32 print(result)  # 输出: 8.0
33 
34 # 4. 格式化 Decimal 对象为字符串:
35 decimal_number = Decimal('3.14159')
36 
37 # 在字符串格式化中,保留两位小数
38 formatted_number = '{:.2f}'.format(decimal_number)
39 print(formatted_number)  # 输出: 3.14

特别注意一下:getcontext().prec = 2

from decimal import Decimal, getcontext
result = Decimal('2.5') * Decimal('1.5')
print(result)  # 输出: 3.75
# 设置精度
getcontext().prec = 2

result = Decimal('2.5') * Decimal('1.5')
print(result)  # 输出: 3.8

当使用 getcontext().prec 设置精度时,可能会遇到以下一些坑:

  1. 精度对于整数运算的影响:当使用整数进行计算时,精度设置可能会导致结果不符合预期。这是因为整数的运算结果不会被截断或舍入,而是被保留为整数。这可能导致结果不符合设置的精度要求。例如:
1 from decimal import Decimal, getcontext
2 
3 getcontext().prec = 2
4 
5 result = Decimal('5') / Decimal('3')
6 print(result)  # 输出: 1

 

在这个示例中,即使设置精度为2,由于整数除法的结果是整数,所以结果被截断为 1 而不是 1.67

  1. 精度对于浮点数运算的影响:当进行浮点数运算时,精度设置可能引入舍入误差。这是因为浮点数运算本身就存在精度问题,而 getcontext().prec 设置的精度只能控制 Decimal 对象的小数位数,无法解决浮点数本身的精度问题。例如:
1 from decimal import Decimal, getcontext
2 
3 getcontext().prec = 2
4 
5 result = Decimal('0.1') + Decimal('0.1') + Decimal('0.1')
6 print(result)  # 输出: 0.3 (可能不准确)

 

在这个示例中,尽管精度设置为2,但由于浮点数的精度问题,结果可能并非完全准确的 0.3

  1. quantize 方法的使用注意事项:quantize 方法用于四舍五入到指定的精度。然而,需要注意的是,该方法会创建一个新的 Decimal 对象,而不是原地修改原始的 Decimal 对象。例如:
1 from decimal import Decimal, getcontext
2 
3 getcontext().prec = 2
4 
5 value = Decimal('3.14159')
6 quantized_value = value.quantize(Decimal('0.01'))
7 print(value)  # 输出: 3.14159
8 print(quantized_value)  # 输出: 3.14

在这个示例中,使用 quantize 方法将 value 四舍五入到两位小数,并将结果存储在 quantized_value 中。原始的 value 对象保持不变。