This question already has an answer here:
Why is it a syntax error to have an object attribute named "del", "return" etc?
(1 answer)
Closed 7 years ago.
I may have stumbled on an illegal variable name
pass = "Pass the monkey!"
print pass
Syntax error: invalid syntax
I'm aware that some keywords are verboten as variables.
Is there the Pythonic equivalent to JavaScript variable name validator?
You can test whether something is a keyword or not using the keyword module
>>> import keyword
>>> keyword.iskeyword("pass")
True
>>> keyword.iskeyword("not_pass")
False
https://docs.python.org/2/library/keyword.html
This module allows a Python program to determine if a string is a
keyword.
keyword.iskeyword(s)
Return true if s is a Python keyword.
Some variable names are illegal in Python because of it being a reserved word.
From the keywords section in the Python docs:
The following identifiers are used as reserved words, or keywords of
the language, and cannot be used as ordinary identifiers. They
must be spelled exactly as written here:
# Complete list of reserved words
and
del
from
not
while
as
elif
global
or
with
assert
else
if
pass
yield
break
except
import
print
class
exec
in
raise
continue
finally
is
return
def
for
lambda
try
True # Python 3 onwards
False # Python 3 onwards
None # Python 3 onwards
nonlocal # Python 3 onwards
async # in Python 3.7
await # in Python 3.7
So, you cannot use any of the above identifiers as a variable name.
This function will check if a name is a keyword in Python or one of Python built-in objects, which can be a function, a constant, a type or an exception class.
import keyword
def is_keyword_or_builtin(name):
return keyword.iskeyword(name) or name in dir(__builtins__)
While you can't use Python keywords as variable names, you are allowed to do it with Python built-ins though it's considered a bad practice so I will recommend to avoid it.
Related
This question already has answers here:
How do I use a keyword as a variable name?
(3 answers)
Closed 2 years ago.
I have stumbled upon the following syntax error with my Python3 interpreter:
class Class:
pass
a = Class()
a.from = 2
a.from = 2
^
SyntaxError: invalid syntax
Assignment of attributes that do not contain .from seem to be working fine:
a = Class()
a.fro = 2
print(a.__dict__)
{'fro': 2}
I understand that the standalone from statement is reserved for imports but struggle to understand why that would matter in the context of a class with the same key in its dict. Can someone explain why the interpreter complains at this point?
Simply because it's a reserved keyword that you can't use as an identifier.
The same issue would arise with e. g. x.in, x.for, x.import,...
This question already has answers here:
How can I get the source code of a Python function?
(13 answers)
Closed 4 years ago.
I recently asked a question with title "python find the type of a function" and got very helpful answers. Here is a related question.
Suppose I import *.py files written by me, and these imports result in f being one of the functions defined by me. Now I write to my python interpreter x = f. Later, I want to see the full definition of f, preferably with comments still in place, knowing only x. Is this possible? Does python remember which file the definition was imported from, which is, of course, not enough to give the full definition of f, unless one can find the actual relevant definition?
The built in help(object) will give you the correct documentation if you alias k to some function you commented - same for inspect.getsource(k) - they know which function is ment by your variable name alias k at this time.
See:
the help() built in
inspect.getsource(k)
(taken from here)
Example:
# reusing this code - created it for some other question today
class well_documented_example_class(object):
"""Totally well documented class"""
def parse(self, message):
"""This method does coool things with your 'message'
'message' : a string with text in it to be parsed"""
self.data = [x.strip() for x in message.split(' ')]
return self.data
# alias for `parse()`:
k = well_documented_example_class.parse
help(k)
Prints:
Help on function parse in module __main__:
parse(self, message)
This method does coool things with your 'message'
'message' : a string with text in it to be parsed
Same goes for inspect.getsource(k):
# from https://stackoverflow.com/a/52333691/7505395
import inspect
print(inspect.getsource(k))
prints:
def parse(self, message):
"""This method does coool things with your 'message'
'message' : a string with text in it to be parsed"""
self.data = [x.strip() for x in message.split(' ')]
return self.data
You should think of the way Python uses variables. You have objects (can be classes, functions, lists, scalars or whatelse) and variables that only hold references to those objects.
That explains why when multiple variables point to the same mutable object, if you change it through one of those variables, the change in visible in all other ones.
This is the same thing here. The function object manages all its attributes: its docstring, its code, and its source (if it has: C function show no source). Assigning the function to a new variable does not hide the object behind anything: you still access the original object.
Things would go differently with decorators, because the decorator creates a new object, and the original object is only available to the decorated one.
I realize the question is a bit specific, sorry.
I'm trying to solve a python puzzle where what I input get exec'ed. My aim is to store something of arbitrary length in the global name space (e.g, change the variable target). You'll see below that my input is limited to 35 chars.
Here's the program:
#!/usr/bin/env python2
from sys import modules
modules.clear()
del modules
raw_input2 = raw_input
exception2 = Exception
__builtins__.__dict__.clear()
__builtins__ = None
target = None # change this !
while 1:
try:
scope = {'r':0}
exec 'r = ' + raw_input2()[:35] in scope
print 'Result:', scope['r']
except exception2, e:
print "Error: ", e
As said, my point is to store data somewhere, since vars get reset each loop.
I know I could use globals()['target']=xxx, but the builtins were disabled.
In theory I could use global target;target=xxx but this executes in scope, not in the global scope (also I think the global keyword must come at the beginning of the anonymous function)
I know all variables are stored in some __dict__ object, but the only way I know to write in it is via globals()['target']=xxx which is disabled
I know you can painfully access the super-object with ().__class__.__base__, but with the limit of 35 characters, it doesn't seem to be the way (this string alone is 21 chars already, you need two more to start with 0;, so only 11 char remaining to assign something...).
Any ideas ?
Thanks!
The answer is: write in __builtins__.
Example input:
1;__builtins__['a']="string1"
Result: 1
1;__builtins__['a']+="string2"
... which actually seems very simple since it is right above the variable marked # change this in the question. I do not fully understand yet why the __builtins__ var is passed in the exec scope, especially since it should be None (and hence not a dictionary), but is assignable like a dictionary.
But it works, tested in python 2.7
In python, one can attribute some values to some of the keywords that are already predefined in python, unlike other languages. Why?
This is not all, some.
> range = 5
> range
> 5
But for
> def = 5
File "<stdin>", line 1
def = 5
^
SyntaxError: invalid syntax
One possible hypothesis is - Lazy coders with unique parsing rules.
For those new to python, yeah, this actually works, for keywords like True, False, range, len, so on.
I wrote a compiler for python in college and, if I remember correctly, the keywords list did not have them.
While range is nothing but a built-in function, def is a keyword. (Most IDEs should indicate the difference with appropriate colors.)
Functions - whether built-in or not - can be redefined. And they don't have to remain functions, but can become integers like range in your example. But you can never redefine keywords.
If you wish, you can print the list of all Python keywords with the following lines of code (borrowed from here):
import keyword
for keyword in keyword.kwlist:
print keyword
Output:
and
as
assert
break
class
continue
def
del
elif
else
except
exec
finally
for
from
global
if
import
in
is
lambda
not
or
pass
print
raise
return
try
while
with
yield
And for Python 3 (notice the absence of print):
False
None
True
and
as
assert
break
class
continue
def
del
elif
else
except
finally
for
from
global
if
import
in
is
lambda
nonlocal
not
or
pass
raise
return
try
while
with
yield
In contrast, the built-in functions can be found here: https://docs.python.org/2/library/functions.html
The keyword 'range' is a function, you can create some other vars as well as sum, max...
In the other hand, keyword 'def' expects a defined structure in order to create a function.
def <functionName>(args):
You are confused between keywords and built-in functions. def is a keyword, but range and len are simply built-in functions. Any function can always be overridden, but a keyword cannot.
The full list of keywords can be found in keywords.kwlist.
This question already has answers here:
How do I check if a variable exists?
(14 answers)
Closed 8 years ago.
This will work fine:
a = 1
if a:
b = a
but this will not work:
if a:
b = a
it is not like this "if" statement will be executed given that we are explicitly saying..
"if a exists"
so why does it error ? if it does not exist then simply do not do anything within the parameters of that if statement.
UPDATE
it turns out "if a" means.. "if a value for a" means in python.
i am looking for the equivalency for "if a exists at all then move forward"
You can use locals():
if 'a' in locals():
# variable 'a' is defined
You can also use Python's principle that it's easier to ask for forgiveness than permission:
try:
b
# if we get here, variable 'b' is defined
except NameError:
# variable 'b' is not defined
As mentioned in the documentation:
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements.
When a name doesn't exist (hasn't been bound to, so there are no assignments binding a value to it, no import statements exist that assign an imported object to the name and no function arguments exist), then Python throws an exception.
You can handle that exception; a global name throws NameError, a local name throws an UnboundLocalError. Catching the exception with a try...except statement also can tell you if the exception wasn't thrown:
try:
somename
except NameError:
# name does not exist
else:
# name exists
See the Execution model documentation on what makes a name exist or not.