简体   繁体   中英

Why can you assign values to built-in functions in Python?

I found out about this by accident today when I noticed that a piece of Python code had used the built-in function all as a variable identifier to store the result of a list comprehension and it didn't throw an error, so I tried the following:

type('abc')
Out[1]: str

type('abc') == str
Out[2]: True

str = int

type('abc') == str
Out[4]: False

type('abc')
Out[5]: str

type = [1,2,3]

type('abc')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-a74a7df76db1> in <module>()
----> 1 type('abc')

TypeError: 'list' object is not callable 

Hopefully, it's a valid question when I ask why this behavior is allowed in Python.

Or better yet, how do I make sure that a built-in function like str is really str and not say, int so str(123) won't be evaluated as int(123) by accident?

Python expects you to take responsibility for your code, is why. Python doesn't have private attributes, no protected classes, and almost no limits on what names you can use.

Yes, that means you can accidentally rename a built-in. Create unittests for your code, use a linter, and generally, you'll quickly learn to spot accidental use of a built-in you needed. It's no different from accidentally re-using any other name in your code.

Note that you are simply masking the built-in names; name lookups that fail to find a global next look at the built-in namespace, so if you set str to something else, that is found before the built-in. Simply delete the global:

>>> str = 'foobar'
>>> isinstance('foobar', str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
>>> del str
>>> isinstance('foobar', str)
True

The alternative would be to make every built-in name a reserved keyword, leaving you with a much diminished list of names that is allowed, and no flexibility in re-defining those objects. Python 2.7 has 144 such names, for example.

In this context, see this blog post by Guido van Rossum on why None , True and False are now keywords in Python 3 :

Because you cannot use these as variable or function names anywhere, ever, in any Python program, everyone using Python has to know about all the reserved words in the language, even if they don't have any need for them. For this reason, we try to keep the list of reserved words small, and the core developers hem and haw a lot before adding a new reserved word to the language.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM