def type_check(correct_type):def outer(func):def inner(arg):if(type(arg) == correct_type):return func(arg)else:return "参数类型错误!"return innerreturn outerprint("<<<--- 测试整数 --->>>")@type_check(int)def double(x):return x * 2print(double(2)) # 这里打印结果应该是 4print(double("2")) # 这里打印结果应该是 “参数类型错误”print("\n<<<--- 测试字符串 --->>>")@type_check(str)def upper(s):return s.upper()print(upper('I love FishC.')) # 这里打印结果应该是 I LOVE FISHCprint(upper(250)) # 这里打印结果应该是 “参数类型错误”
这段代码展示了如何使用 Python 装饰器实现参数类型检查。我们将逐步分析每一行代码,解释其功能和执行顺序。
### 1. 定义装饰器 `type_check`
```python
def type_check(correct_type):
def outer(func):
def inner(arg):
if(type(arg) == correct_type):
return func(arg)
else:
return "参数类型错误!"
return inner
return outer
```
- **外层函数 `type_check(correct_type)`**:
- 接受一个参数 `correct_type`,用于指定正确的类型。
- `correct_type` 是装饰器用来验证参数类型的目标类型(例如 `int` 或 `str`)。
- **中层函数 `outer(func)`**:
- `outer` 是一个装饰器,它接受一个函数 `func` 作为参数,并返回一个内部函数 `inner`,用于替换原始的 `func` 函数。
- **内层函数 `inner(arg)`**:
- `inner` 是实际执行类型检查的地方。它接受一个参数 `arg`,并检查其类型是否与 `correct_type` 相同。
- 如果 `arg` 的类型与 `correct_type` 相同,`inner` 就会调用并返回原函数 `func(arg)` 的结果。
- 如果 `arg` 的类型不匹配,则返回 `"参数类型错误!"`。
### 2. 应用装饰器 `@type_check(int)`
```python
@type_check(int)
def double(x):
return x * 2
```
- `@type_check(int)` 是装饰器的应用,它会替代 `double(x)` 函数。
- 使用 `@type_check(int)` 时,`correct_type` 会被赋值为 `int`,因此在调用 `double` 函数时,会检查传入参数的类型是否为 `int`。
- `double(x)` 函数的功能是将参数 `x` 乘以 2。
### 3. 测试整数类型
```python
print("<<<--- 测试整数 --->>>")
print(double(2)) # 这里打印结果应该是 4
print(double("2")) # 这里打印结果应该是 “参数类型错误”
```
- **第一次调用 `double(2)`**:
- `double(2)` 被传入的参数 `2` 是一个整数,符合 `type_check(int)` 装饰器的类型检查条件。
- 装饰器检查参数类型是否为 `int`,结果为真。
- 调用 `double(2)` 内部的 `return x * 2`,计算结果为 `4`,因此输出 `4`。
- **第二次调用 `double("2")`**:
- `double("2")` 被传入的参数是字符串 `"2"`,类型是 `str`,不符合 `type_check(int)` 的要求。
- 装饰器检测到参数类型错误,返回 `"参数类型错误!"`。
### 4. 应用装饰器 `@type_check(str)`
```python
print("\n<<<--- 测试字符串 --->>>")
@type_check(str)
def upper(s):
return s.upper()
```
- `@type_check(str)` 应用于 `upper(s)` 函数,`correct_type` 被赋值为 `str`。
- `upper(s)` 的功能是将字符串 `s` 转换为大写形式。
### 5. 测试字符串类型
```python
print(upper('I love FishC.')) # 这里打印结果应该是 I LOVE FISHC
print(upper(250)) # 这里打印结果应该是 “参数类型错误”
```
- **第一次调用 `upper('I love FishC.')`**:
- 传入的参数 `'I love FishC.'` 是一个字符串,符合 `type_check(str)` 的要求。
- 装饰器通过类型检查,允许调用 `upper('I love FishC.')`,返回转换为大写后的字符串 `"I LOVE FISHC."`。
- **第二次调用 `upper(250)`**:
- 传入的参数 `250` 是一个整数,类型为 `int`,不符合 `type_check(str)` 的要求。
- 装饰器检测到类型错误,返回 `"参数类型错误!"`。
### 总结执行流程
1. `type_check(int)` 装饰器被应用于 `double(x)` 函数,检查传入参数是否是 `int` 类型。
2. `type_check(str)` 装饰器被应用于 `upper(s)` 函数,检查传入参数是否是 `str` 类型。
3. 当调用 `double(2)` 时,参数类型为 `int`,装饰器允许执行并返回 `4`。
4. 当调用 `double("2")` 时,参数类型为 `str`,装饰器返回 `"参数类型错误!"`。
5. 当调用 `upper('I love FishC.')` 时,参数类型为 `str`,装饰器允许执行并返回大写字符串 `"I LOVE FISHC."`。
6. 当调用 `upper(250)` 时,参数类型为 `int`,装饰器返回 `"参数类型错误!"`。
### 完整代码及输出:
```python
def type_check(correct_type):
def outer(func):
def inner(arg):
if(type(arg) == correct_type):
return func(arg)
else:
return "参数类型错误!"
return inner
return outer
print("<<<--- 测试整数 --->>>")
@type_check(int)
def double(x):
return x * 2
print(double(2)) # 这里打印结果应该是 4
print(double("2")) # 这里打印结果应该是 “参数类型错误”
print("\n<<<--- 测试字符串 --->>>")
@type_check(str)
def upper(s):
return s.upper()
print(upper('I love FishC.')) # 这里打印结果应该是 I LOVE FISHC
print(upper(250)) # 这里打印结果应该是 “参数类型错误”
```
### 输出:
```
<<<--- 测试整数 --->>>
4
参数类型错误!
<<<--- 测试字符串 --->>>
I LOVE FISHC.
参数类型错误!
```
### 总结:
- 装饰器 `type_check` 实现了类型检查的功能,根据传入的目标类型(`int` 或 `str`)验证函数参数的类型。
- 如果参数类型正确,执行原函数;如果参数类型错误,返回提示信息 `"参数类型错误!"`。