Administrator
发布于 2024-06-20 / 7 阅读
0

将python中的关键字或内置函数作为变量名--py学习中的小插曲

在学习b站上的python课的时候看到一个有趣的例子

py中的关键字或者是内置函数(比如print())可以用作变量名来赋值吗,像是print = 123

有趣的问题,我们在编辑器里面试一下

语法上没问题,但是编译会报错,这也不意外

是一个异常类错误,表明int对象不可被调用

print被赋值后成为了一个int型变量,而变量是没有办法作为函数被调用的

虽然不会引发语法错误,但会覆盖内置函数,导致后续无法正常使用该函数。例如:

print = 123 # 覆盖了内置的print函数 
print("Hello, World!") # 这会导致TypeError,因为print现在是一个整数

但是我就是想将print定义为变量并且赋值,我还有别的方法打印print变量吗

当然,这样也可以,有别的野路子

使用 builtins 模块

这是最推荐的方法,因为它在所有 Python 版本中都有效。

import builtins

print = 123
builtins.print(print)  # 输出 123

builtins 模块在 Python 3 中包含所有内置的标识符(函数、异常等)。通过 import builtins,你可以访问到所有内置的函数。

原理:类似于 __builtins__builtins 模块提供了对全局内置函数的访问。通过 import builtins,你可以重新引用到未被覆盖的 print

使用 sys.stdout.write

这个方法在所有情况下都能工作,因为它不依赖于 print 函数。

import sys

print = 123
sys.stdout.write(str(print) + '\n')  # 输出 123

sys.stdout.write 是一个低级的输出函数,可以直接向标准输出(通常是控制台)写入字符串。与 print 不同的是,它不会自动添加换行符,因此需要手动添加。

原理sys.stdout.write 是一个不依赖 print 的函数,可以直接写入输出流,因而不受 print 被覆盖的影响。

使用自定义打印函数

在覆盖 print 之前,将原始的 print 函数存储在另一个变量中。

original_print = print
print = 123
original_print(print)  # 输出 123

你可以定义自己的打印函数,从而避免覆盖内置的 print 函数。这样,即使覆盖了 print,你仍然可以使用自定义的打印函数来输出内容。

原理:在覆盖 print 之前,将原始的 print 函数引用存储在另一个变量中(如 my_print)。覆盖 print 后,my_print 仍然指向原始的 print 函数,从而可以继续使用

示例代码

以下是一个完整的示例,展示了上述有效的方法:

import sys
import builtins

# 将print定义为变量并赋值
print = 123

# 使用builtins.print
builtins.print("使用builtins.print:", print)

# 使用sys.stdout.write
sys.stdout.write("使用sys.stdout.write: " + str(print) + '\n')

# 定义自己的打印函数
def my_print(value):
    builtins.print("使用my_print:", value)

my_print(print)

输出结果

使用builtins.print: 123
使用sys.stdout.write: 123
使用my_print: 123

很有意思是不是,但是print是一个内置函数,如果是python中的关键字呢

def = 123
# SyntaxError: invalid syntax
print(def)
# 上一行代码不会执行,因为前一行代码已经引发了语法错误

很明显,不行,会直接提示语法错误

为什么像print这样的函数就可以作为变量使用,而def不行

关键字和内置函数的区别

  • 关键字(Keyword):关键字是Python语言保留的词汇,它们具有特殊的语法意义。例如,def是用来定义函数的关键字。因此,关键字不能被用作变量名,因为它们在语法上有特定用途。

  • 内置函数(Built-in Function):内置函数是Python标准库提供的函数,如printlen等。虽然不建议,但内置函数可以被重新定义为变量(即覆盖),因为它们不是语法关键字。但是,这样做会使你失去对这些函数的访问,直到你重新启动解释器或取消覆盖。

def是关键字,而print是内置函数

def是关键字,用于定义函数。例如:

def my_function(): pass

如果你尝试将def用作变量名,会引发语法错误:

def = 123 # SyntaxError: invalid syntax

  • print在Python 3中是内置函数,而在Python 2中是关键字(语句)。在Python 3中,可以将print用作变量名,但这会覆盖内置的print函数。例如:

    print = 123 print(print) # 输出 123

    这样做虽然不会引发语法错误,但会导致你无法使用原始的print函数。

为什么覆盖内置函数是可能的,但覆盖关键字是不可能的

关键字是语言的基本组成部分,决定了语言的语法结构。它们在语言解析时被直接识别,因此不可能重新定义关键字。

内置函数虽然是Python标准库的一部分,但它们在运行时被处理,可以被赋值覆盖。然而,这样做不建议,因为它会影响代码的可读性和功能。