Python数据类型:不用声明int/float,Python怎么知道变量是什么类型?
数据类型是编程的基础。Python是动态类型语言,变量无需声明类型,但理解各种数据类型的特性对于编写正确、高效的代码至关重要。本篇将详细介绍Python的内置数据类型,并与C语言进行对比。
- Python数据类型详解
1. 数据类型概览
1.1 Python内置数据类型
Python的内置数据类型可以分为以下几类:
| 类别 | 数据类型 | 说明 |
|---|---|---|
| 数字类型 | int, float, complex | 整数、浮点数、复数 |
| 布尔类型 | bool | True/False |
| 序列类型 | str, list, tuple | 字符串、列表、元组 |
| 映射类型 | dict | 字典(键值对) |
| 集合类型 | set, frozenset | 集合、不可变集合 |
| 空值类型 | NoneType | None |
| 二进制类型 | bytes, bytearray | 字节串 |
📌 本篇重点:数字类型、布尔类型、字符串类型、空值类型。容器类型(列表、字典等)将在下一篇详细介绍。
1.2 动态类型 vs 静态类型
C语言(静态类型):
int a = 10; // 声明时必须指定类型
a = "hello"; // 错误!不能改变类型
float b = 3.14; // 必须声明为float
Python(动态类型):
a = 10 # a是整数
a = "hello" # a变成字符串(合法,但不推荐)
b = 3.14 # 自动推断为浮点数
# 查看类型
print(type(a)) # <class 'str'>
print(type(b)) # <class 'float'>
| 特性 | 静态类型(C) | 动态类型(Python) |
|---|---|---|
| 类型声明 | 必须 | 不需要 |
| 类型检查时机 | 编译时 | 运行时 |
| 变量类型可变 | 不可以 | 可以 |
| 类型错误发现 | 编译时 | 运行时 |
| 开发效率 | 较低 | 较高 |
| 运行效率 | 较高 | 较低 |
2. 数字类型
2.1 整数(int)
Python的整数没有大小限制(只受内存限制),这与C语言的固定位数整数不同。
# 整数定义
a = 10
b = -20
c = 0
# Python整数可以任意大(C语言会溢出)
big_num = 123456789012345678901234567890
print(big_num) # 正常输出,不会溢出
# 不同进制表示
decimal = 255 # 十进制
binary = 0b11111111 # 二进制(0b开头)
octal = 0o377 # 八进制(0o开头)
hexadecimal = 0xFF # 十六进制(0x开头)
print(decimal, binary, octal, hexadecimal) # 都是255
# 数字分隔符(提高可读性,Python 3.6+)
million = 1_000_000
binary = 0b1111_0000_1111_0000
print(million) # 1000000
与C语言对比:
| 特性 | C语言 | Python |
|---|---|---|
| 整数范围 | 固定(如int为32位) | 无限制 |
| 溢出 | 会溢出 | 不会溢出 |
| 进制表示 | 0x, 0, 0b | 0x, 0o, 0b |
| 类型 | int, long, short等 | 统一为int |
// C语言整数溢出
int max_int = 2147483647;
printf("%d\n", max_int + 1); // -2147483648(溢出)
# Python不会溢出
max_int = 2147483647
print(max_int + 1) # 2147483648(正确)
2.2 浮点数(float)
Python的浮点数使用双精度(64位),相当于C语言的double。
# 浮点数定义
a = 3.14
b = -0.001
c = 2.5e10 # 科学计数法:2.5 × 10^10
d = 1.5e-3 # 0.0015
# 浮点数精度问题(所有语言都有)
print(0.1 + 0.2) # 0.30000000000000004
# 解决精度问题
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3
# 浮点数比较
a = 0.1 + 0.2
b = 0.3
print(a == b) # False(不要直接比较)
# 正确的比较方式
import math
print(math.isclose(a, b)) # True
# 或
print(abs(a - b) < 1e-9) # True
特殊浮点值:
# 正无穷和负无穷
pos_inf = float('inf')
neg_inf = float('-inf')
# 非数字(NaN)
nan = float('nan')
print(pos_inf > 1e308) # True
print(math.isnan(nan)) # True
print(math.isinf(pos_inf)) # True
2.3 复数(complex)
Python内置支持复数,这是C语言不直接支持的。
# 复数定义(j表示虚部)
z1 = 3 + 4j
z2 = complex(3, 4) # 等价写法
# 获取实部和虚部
print(z1.real) # 3.0
print(z1.imag) # 4.0
# 复数运算
z3 = z1 + z2 # (6+8j)
z4 = z1 * z2 # (-7+24j)
# 共轭复数
print(z1.conjugate()) # (3-4j)
# 复数模(绝对值)
print(abs(z1)) # 5.0(即sqrt(3²+4²))
💡 FPGA应用:复数在信号处理中很常见,如FFT运算。Python的复数支持可以方便地进行算法验证。
2.4 数字类型转换
# 整数转换
int(3.14) # 3(截断小数部分)
int(3.9) # 3(不是四舍五入)
int("42") # 42(字符串转整数)
int("1010", 2) # 10(二进制字符串转整数)
int("ff", 16) # 255(十六进制字符串转整数)
# 浮点数转换
float(10) # 10.0
float("3.14") # 3.14
# 四舍五入
round(3.14159, 2) # 3.14
round(3.5) # 4(Python 3使用银行家舍入法)
round(2.5) # 2(注意:不是3!)
# 向上/向下取整
import math
math.floor(3.7) # 3(向下取整)
math.ceil(3.2) # 4(向上取整)
math.trunc(3.7) # 3(截断)
math.trunc(-3.7) # -3(截断)
2.5 常用数学函数
import math
# 基本运算
abs(-10) # 10(绝对值)
pow(2, 10) # 1024(幂运算)
2 ** 10 # 1024(幂运算符)
divmod(17, 5) # (3, 2)(商和余数)
# math模块
math.sqrt(16) # 4.0(平方根)
math.pow(2, 10) # 1024.0
math.log(100, 10) # 2.0(对数)
math.log2(8) # 3.0
math.log10(100) # 2.0
math.exp(1) # 2.718...(e的幂)
# 三角函数(弧度制)
math.sin(math.pi / 2) # 1.0
math.cos(0) # 1.0
math.tan(math.pi / 4) # 1.0
math.radians(180) # 3.14...(角度转弧度)
math.degrees(math.pi) # 180.0(弧度转角度)
# 常量
math.pi # 3.141592653589793
math.e # 2.718281828459045
math.inf # 无穷大
math.nan # 非数字
3. 布尔类型(bool)
3.1 布尔值
Python的布尔类型只有两个值:True和False(注意首字母大写)。
# 布尔值
is_valid = True
is_empty = False
# 布尔值是整数的子类
print(isinstance(True, int)) # True
print(True == 1) # True
print(False == 0) # True
print(True + True) # 2
# 比较运算返回布尔值
print(5 > 3) # True
print(5 == 3) # False
print(5 != 3) # True
与C语言对比:
| 特性 | C语言 | Python |
|---|---|---|
| 布尔类型 | _Bool(C99)或用int | bool |
| 真值 | 非0 | True |
| 假值 | 0 | False |
| 大小写 | true/false(C99) | True/False |
3.2 布尔运算
# 逻辑运算符
print(True and False) # False
print(True or False) # True
print(not True) # False
# 与C语言对比
# C: && || !
# Python: and or not
# 短路求值
def check():
print("check被调用")
return True
# and短路:第一个为False时,不执行第二个
False and check() # 不会打印
# or短路:第一个为True时,不执行第二个
True or check() # 不会打印
3.3 真值测试
Python中,以下值被视为False,其他所有值都是True:
| 假值 | 说明 |
|---|---|
False | 布尔假 |
None | 空值 |
0 | 整数零 |
0.0 | 浮点数零 |
"" | 空字符串 |
[] | 空列表 |
{} | 空字典 |
() | 空元组 |
set() | 空集合 |
# 真值测试
if []:
print("非空")
else:
print("空列表") # 输出这个
# 常用的简洁写法
my_list = []
# 不推荐
if len(my_list) == 0:
print("空")
# 推荐
if not my_list:
print("空")
# 检查变量是否有值
name = ""
if name:
print(f"你好,{name}")
else:
print("请输入姓名")
4. 字符串类型(str)
4.1 字符串定义
Python字符串是不可变的Unicode字符序列。
# 单引号和双引号等价
s1 = 'Hello'
s2 = "Hello"
# 包含引号的字符串
s3 = "He said 'Hello'"
s4 = 'He said "Hello"'
s5 = "He said \"Hello\"" # 转义
# 三引号:多行字符串
s6 = """这是
多行
字符串"""
s7 = '''也可以
用单引号'''
# 原始字符串(不转义)
path = r"C:\Users\name\Documents" # r前缀
print(path) # C:\Users\name\Documents
# 字符串拼接
s8 = "Hello" + " " + "World"
s9 = "Hello" " " "World" # 相邻字符串自动拼接
s10 = "Ha" * 3 # "HaHaHa"
4.2 字符串索引与切片
s = "Hello, World!"
# 索引(从0开始)
print(s[0]) # 'H'
print(s[7]) # 'W'
print(s[-1]) # '!'(负索引从末尾开始)
print(s[-2]) # 'd'
# 切片 [start:end:step]
print(s[0:5]) # 'Hello'(不包含end)
print(s[7:12]) # 'World'
print(s[:5]) # 'Hello'(省略start,从头开始)
print(s[7:]) # 'World!'(省略end,到末尾)
print(s[::2]) # 'Hlo ol!'(步长为2)
print(s[::-1]) # '!dlroW ,olleH'(反转字符串)
# 切片不会越界
print(s[0:100]) # 'Hello, World!'(不报错)
索引图示:
字符串: H e l l o , W o r l d !
正索引: 0 1 2 3 4 5 6 7 8 9 10 11 12
负索引:-13-12-11-10 -9 -8 -7 -6 -5 -4 -3 -2 -1
4.3 字符串常用方法
s = " Hello, World! "
# 大小写转换
s.upper() # ' HELLO, WORLD! '
s.lower() # ' hello, world! '
s.title() # ' Hello, World! '
s.capitalize() # ' hello, world! '
s.swapcase() # ' hELLO, wORLD! '
# 去除空白
s.strip() # 'Hello, World!'(两端)
s.lstrip() # 'Hello, World! '(左端)
s.rstrip() # ' Hello, World!'(右端)
# 查找与替换
s = "Hello, World!"
s.find('o') # 4(第一个'o'的位置)
s.find('o', 5) # 8(从位置5开始找)
s.find('x') # -1(找不到返回-1)
s.index('o') # 4(找不到会报错)
s.count('o') # 2(出现次数)
s.replace('o', '0') # 'Hell0, W0rld!'
# 判断方法
s.startswith('Hello') # True
s.endswith('!') # True
s.isdigit() # False(是否全是数字)
s.isalpha() # False(是否全是字母)
s.isalnum() # False(是否全是字母或数字)
s.isspace() # False(是否全是空白)
# 分割与连接
s = "apple,banana,cherry"
s.split(',') # ['apple', 'banana', 'cherry']
'-'.join(['a', 'b', 'c']) # 'a-b-c'
# 对齐
s = "Hi"
s.center(10) # ' Hi '
s.ljust(10) # 'Hi '
s.rjust(10) # ' Hi'
s.zfill(5) # '000Hi'
4.4 字符串与C语言对比
| 特性 | C语言 | Python |
|---|---|---|
| 类型 | char[]或char* | str |
| 结束符 | \0 | 无需 |
| 可变性 | 可变 | 不可变 |
| 长度获取 | strlen() | len() |
| 拼接 | strcat() | +或join() |
| 比较 | strcmp() | == |
| 索引 | s[i] | s[i] |
| 切片 | 手动实现 | s[start:end] |
// C语言字符串操作
char s1[20] = "Hello";
char s2[] = "World";
strcat(s1, s2); // 拼接
int len = strlen(s1); // 长度
if (strcmp(s1, s2) == 0) { } // 比较
# Python字符串操作
s1 = "Hello"
s2 = "World"
s3 = s1 + s2 # 拼接
length = len(s1) # 长度
if s1 == s2: # 比较
pass
5. 空值类型(NoneType)
None是Python中表示”无”或”空”的特殊值,类似于C语言的NULL。
# None的使用
result = None
# 函数没有return时返回None
def no_return():
pass
print(no_return()) # None
# 判断是否为None
if result is None:
print("结果为空")
# 注意:用is而不是==
x = None
print(x is None) # True(推荐)
print(x == None) # True(不推荐)
# None与False的区别
print(None == False) # False
print(bool(None)) # False(None在布尔上下文中为假)
与C语言NULL对比:
| 特性 | C语言NULL | Python None |
|---|---|---|
| 含义 | 空指针 | 空值对象 |
| 类型 | 指针类型 | NoneType |
| 值 | 0或(void*)0 | 单例对象 |
| 比较 | == NULL | is None |
6. 类型检查与转换
6.1 类型检查
# type():获取类型
print(type(10)) # <class 'int'>
print(type(3.14)) # <class 'float'>
print(type("hello")) # <class 'str'>
print(type(True)) # <class 'bool'>
print(type(None)) # <class 'NoneType'>
# isinstance():检查是否是某类型(推荐)
print(isinstance(10, int)) # True
print(isinstance(10, (int, float))) # True(多类型检查)
print(isinstance(True, int)) # True(bool是int的子类)
# type() vs isinstance()
class MyInt(int):
pass
x = MyInt(10)
print(type(x) == int) # False
print(isinstance(x, int)) # True(推荐)
6.2 类型转换
# 转整数
int(3.14) # 3
int("42") # 42
int("1010", 2) # 10(二进制)
int(True) # 1
# 转浮点数
float(10) # 10.0
float("3.14") # 3.14
float(True) # 1.0
# 转字符串
str(42) # "42"
str(3.14) # "3.14"
str(True) # "True"
str([1, 2, 3]) # "[1, 2, 3]"
# 转布尔
bool(0) # False
bool(1) # True
bool("") # False
bool("hello") # True
bool([]) # False
bool([1, 2]) # True
# 进制转换
bin(10) # '0b1010'(二进制字符串)
oct(10) # '0o12'(八进制字符串)
hex(255) # '0xff'(十六进制字符串)
# ASCII转换
ord('A') # 65(字符转ASCII码)
chr(65) # 'A'(ASCII码转字符)
7. 可变类型与不可变类型
Python的数据类型分为可变和不可变两类:
| 类型 | 可变性 | 示例 |
|---|---|---|
int | 不可变 | x = 10 |
float | 不可变 | x = 3.14 |
bool | 不可变 | x = True |
str | 不可变 | x = "hello" |
tuple | 不可变 | x = (1, 2, 3) |
list | 可变 | x = [1, 2, 3] |
dict | 可变 | x = {"a": 1} |
set | 可变 | x = {1, 2, 3} |
不可变类型的含义:
# 字符串不可变
s = "hello"
# s[0] = 'H' # TypeError: 'str' object does not support item assignment
# 只能创建新字符串
s = "H" + s[1:] # "Hello"
# 整数不可变(重新赋值是创建新对象)
x = 10
print(id(x)) # 内存地址
x = x + 1
print(id(x)) # 地址变了,说明是新对象
💡 理解:不可变类型的”修改”实际上是创建新对象,原对象不变。这与C语言的变量概念不同。
8. Python vs C语言:数据类型对比
| 数据类型 | C语言 | Python | 备注 |
|---|---|---|---|
| 整数 | int, long, short | int | Python无大小限制 |
| 浮点数 | float, double | float | Python相当于double |
| 字符 | char | str(长度1) | Python无单独字符类型 |
| 字符串 | char[] | str | Python字符串不可变 |
| 布尔 | _Bool, int | bool | Python有专门类型 |
| 空值 | NULL | None | 概念不同 |
| 数组 | int[] | list | Python列表更灵活 |
| 结构体 | struct | class/dict | Python更灵活 |
| 指针 | int* | 无 | Python无指针 |
| 枚举 | enum | Enum类 | Python需导入enum模块 |
9. 常见错误与避坑
❌ 错误1:浮点数精度问题
# 错误:直接比较浮点数
if 0.1 + 0.2 == 0.3:
print("相等") # 不会执行
# 正确:使用误差范围
if abs((0.1 + 0.2) - 0.3) < 1e-9:
print("相等")
# 或使用math.isclose
import math
if math.isclose(0.1 + 0.2, 0.3):
print("相等")
❌ 错误2:字符串转数字失败
# 错误:字符串包含非数字字符
# int("3.14") # ValueError
# int("abc") # ValueError
# 正确:先检查或使用try-except
s = "3.14"
try:
num = float(s)
except ValueError:
print("无法转换")
❌ 错误3:修改不可变类型
# 错误:尝试修改字符串
s = "hello"
# s[0] = 'H' # TypeError
# 正确:创建新字符串
s = 'H' + s[1:]
❌ 错误4:整数除法
# Python 3中/是真除法
print(7 / 2) # 3.5(不是3)
print(7 // 2) # 3(整数除法用//)
# C语言中7/2=3
❌ 错误5:布尔值大小写
# 错误:小写
# if true: # NameError: name 'true' is not defined
# 正确:首字母大写
if True:
pass
10. 实战练习
练习1:数字类型转换
"""
练习:实现一个进制转换器
输入一个十进制数,输出其二进制、八进制、十六进制表示
"""
num = int(input("请输入一个十进制整数:"))
print(f"十进制:{num}")
print(f"二进制:{bin(num)}")
print(f"八进制:{oct(num)}")
print(f"十六进制:{hex(num)}")
# 去掉前缀的写法
print(f"二进制(无前缀):{num:b}")
print(f"八进制(无前缀):{num:o}")
print(f"十六进制(无前缀):{num:x}")
练习2:字符串处理
"""
练习:统计字符串信息
"""
text = input("请输入一段文字:")
print(f"总字符数:{len(text)}")
print(f"字母数:{sum(c.isalpha() for c in text)}")
print(f"数字数:{sum(c.isdigit() for c in text)}")
print(f"空格数:{text.count(' ')}")
print(f"大写字母数:{sum(c.isupper() for c in text)}")
print(f"小写字母数:{sum(c.islower() for c in text)}")
练习3:类型判断
"""
练习:实现一个类型检查函数
"""
def check_type(value):
"""检查并打印值的类型信息"""
print(f"值:{value}")
print(f"类型:{type(value).__name__}")
print(f"布尔值:{bool(value)}")
print(f"字符串表示:{repr(value)}")
print("-" * 30)
# 测试
check_type(42)
check_type(3.14)
check_type("hello")
check_type(True)
check_type(None)
check_type([1, 2, 3])
check_type({})
11. 总结
🔑 核心要点
| 知识点 | 要点 |
|---|---|
| 动态类型 | 变量无需声明类型,运行时确定 |
| 整数 | 无大小限制,支持多种进制 |
| 浮点数 | 双精度,注意精度问题 |
| 布尔 | True/False,首字母大写 |
| 字符串 | 不可变,支持索引和切片 |
| None | 空值,用is None判断 |
| 类型转换 | int(), float(), str(), bool() |
✅ 学习检查清单
- 理解动态类型与静态类型的区别
- 掌握整数的不同进制表示
- 了解浮点数精度问题及解决方法
- 掌握布尔类型和真值测试
- 熟练使用字符串索引和切片
- 掌握常用字符串方法
- 理解可变与不可变类型的区别
📖 下一步学习
掌握了基本数据类型后,让我们学习Python的容器类型(列表、元组、字典、集合):
常见问题 FAQ
💬 Python的int没有大小限制,那会不会很慢?
小整数(-5到256)Python会缓存复用,速度和C一样。大整数确实比C的固定宽度int慢,但日常使用不会感知到差异。只有在高性能计算中才需要关注。
💬 浮点数0.1+0.2!=0.3怎么办?
这是IEEE 754标准的问题,C语言也有。Python中用decimal.Decimal或math.isclose()处理。金融计算务必用Decimal。
📘 系列导航
- 上一篇:03 - Python基本语法与代码风格
- 当前:04 - Python数据类型详解
- 下一篇:05 - Python容器类型详解