Beginning Python - From Novice to Professional
Beginning Python - From Novice to Professional Beginning Python - From Novice to Professional
CHAPTER 5 ■ CONDITIONALS, LOOPS, AND SOME OTHER STATEMENTS 105 >>> from math import sqrt >>> exec "sqrt = 1" >>> sqrt(4) Traceback (most recent call last): File "", line 1, in ? sqrt(4) TypeError: object is not callable: 1 Well, why would you do something like that in the first place, you ask? The exec statement is mainly useful when you build the code string on the fly. And if the string is built from parts that you get from other places, and possibly from the user, you can rarely be certain of exactly what it will contain. So to be safe, you give it a dictionary, which will work as a namespace for it. ■Note The concept of namespaces, or scopes, is a very important one. You will look at it in depth in the next chapter, but for now you can think of a namespace as a place where you keep your variables, much like an invisible dictionary. So when you execute an assignment like x = 1, you store the key x with the value 1 in the current namespace, which will often be the global namespace (which we have been using, for the most part, up until now), but doesn’t have to be. You do this by adding in , where is some dictionary that will function as the namespace for your code string: >>> from math import sqrt >>> scope = {} >>> exec 'sqrt = 1' in scope >>> sqrt(4) 2.0 >>> scope['sqrt'] 1 As you can see, the potentially destructive code does not overwrite the sqrt function; the function works just like it should, and the sqrt variable resulting from the exec’ed assignment is available from the scope. Note that if you try to print out scope, you see that it contains a lot of stuff because the dictionary called __builtins__ is automatically added and contains all built-in functions and values: >>> len(scope) 2 >>> scope.keys() ['sqrt', '__builtins__'] eval A built-in function that is similar to exec is eval (for “evaluate”). Just as exec executes a series of Python statements, eval evaluates a Python expression (written in a string) and returns the
106 CHAPTER 5 ■ CONDITIONALS, LOOPS, AND SOME OTHER STATEMENTS value. (exec doesn’t return anything because it is a statement itself.) For example, you can use the following to make a Python calculator: >>> eval(raw_input("Enter an arithmetic expression: ")) Enter an arithmetic expression: 6 + 18 * 2 42 ■Note The expression eval(raw_input(...)) is, in fact, equivalent to input(...). You can supply a namespace with eval, just as with exec, although expressions rarely rebind variables in the way statements usually do. (In fact, you can supply eval with two namespaces, one global and one local. The global one must be a dictionary, but the local one may be any mapping.) ■Caution Even though expressions don’t rebind variables as a rule, they certainly can (for example by calling functions that rebind global variables). Therefore, using eval with an untrusted piece of code is no safer than using exec. There is, at present, no safe way of executing untrusted code in Python. One alternative is to use an implementation of Python such as Jython (see Chapter 17) and use the some native mechanism such as the Java sandbox. PRIMING THE SCOPE When supplying a namespace for exec or eval, you can also put some values in before actually using the namespace: >>> scope = {} >>> scope['x'] = 2 >>> scope['y'] = 3 >>> eval('x * y', scope) 6 In the same way, a scope from one exec or eval call can be used again in another one: >>> scope = {} >>> exec 'x = 2' in scope >>> eval('x*x', scope) 4 Actually, exec and eval are not used all that often, but they can be nice tools to keep in your back pocket (figuratively, of course).
- Page 86 and 87: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 88 and 89: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 90 and 91: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 92 and 93: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 94 and 95: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 96 and 97: CHAPTER 3 ■ WORKING WITH STRINGS
- Page 98 and 99: CHAPTER 4 ■ ■ ■ Dictionaries:
- Page 100 and 101: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 102 and 103: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 104 and 105: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 106 and 107: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 108 and 109: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 110: CHAPTER 4 ■ DICTIONARIES: WHEN IN
- Page 113 and 114: 82 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 115 and 116: 84 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 117 and 118: 86 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 119 and 120: 88 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 121 and 122: 90 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 123 and 124: 92 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 125 and 126: 94 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 127 and 128: 96 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 129 and 130: 98 CHAPTER 5 ■ CONDITIONALS, LOOP
- Page 131 and 132: 100 CHAPTER 5 ■ CONDITIONALS, LOO
- Page 133 and 134: 102 CHAPTER 5 ■ CONDITIONALS, LOO
- Page 135: 104 CHAPTER 5 ■ CONDITIONALS, LOO
- Page 139 and 140: 108 CHAPTER 5 ■ CONDITIONALS, LOO
- Page 141 and 142: 110 CHAPTER 6 ■ ABSTRACTION But w
- Page 143 and 144: 112 CHAPTER 6 ■ ABSTRACTION ■Ti
- Page 145 and 146: 114 CHAPTER 6 ■ ABSTRACTION Can I
- Page 147 and 148: 116 CHAPTER 6 ■ ABSTRACTION stora
- Page 149 and 150: 118 CHAPTER 6 ■ ABSTRACTION 4. Yo
- Page 151 and 152: 120 CHAPTER 6 ■ ABSTRACTION The p
- Page 153 and 154: 122 CHAPTER 6 ■ ABSTRACTION >>> p
- Page 155 and 156: 124 CHAPTER 6 ■ ABSTRACTION Also,
- Page 157 and 158: 126 CHAPTER 6 ■ ABSTRACTION Feel
- Page 159 and 160: 128 CHAPTER 6 ■ ABSTRACTION ■No
- Page 161 and 162: 130 CHAPTER 6 ■ ABSTRACTION So yo
- Page 163 and 164: 132 CHAPTER 6 ■ ABSTRACTION numer
- Page 165 and 166: 134 CHAPTER 6 ■ ABSTRACTION LAMBD
- Page 167 and 168: 136 CHAPTER 6 ■ ABSTRACTION In th
- Page 169 and 170: 138 CHAPTER 6 ■ ABSTRACTION Scope
- Page 171 and 172: 140 CHAPTER 7 ■ MORE ABSTRACTION
- Page 173 and 174: 142 CHAPTER 7 ■ MORE ABSTRACTION
- Page 175 and 176: 144 CHAPTER 7 ■ MORE ABSTRACTION
- Page 177 and 178: 146 CHAPTER 7 ■ MORE ABSTRACTION
- Page 179 and 180: 148 CHAPTER 7 ■ MORE ABSTRACTION
- Page 181 and 182: 150 CHAPTER 7 ■ MORE ABSTRACTION
- Page 183 and 184: 152 CHAPTER 7 ■ MORE ABSTRACTION
- Page 185 and 186: 154 CHAPTER 7 ■ MORE ABSTRACTION
CHAPTER 5 ■ CONDITIONALS, LOOPS, AND SOME OTHER STATEMENTS 105<br />
>>> from math import sqrt<br />
>>> exec "sqrt = 1"<br />
>>> sqrt(4)<br />
Traceback (most recent call last):<br />
File "", line 1, in ?<br />
sqrt(4)<br />
TypeError: object is not callable: 1<br />
Well, why would you do something like that in the first place, you ask? The exec statement<br />
is mainly useful when you build the code string on the fly. And if the string is built from parts<br />
that you get from other places, and possibly from the user, you can rarely be certain of exactly<br />
what it will contain. So <strong>to</strong> be safe, you give it a dictionary, which will work as a namespace for it.<br />
■Note The concept of namespaces, or scopes, is a very important one. You will look at it in depth in the<br />
next chapter, but for now you can think of a namespace as a place where you keep your variables, much like<br />
an invisible dictionary. So when you execute an assignment like x = 1, you s<strong>to</strong>re the key x with the value 1<br />
in the current namespace, which will often be the global namespace (which we have been using, for the most<br />
part, up until now), but doesn’t have <strong>to</strong> be.<br />
You do this by adding in , where is some dictionary that will function as<br />
the namespace for your code string:<br />
>>> from math import sqrt<br />
>>> scope = {}<br />
>>> exec 'sqrt = 1' in scope<br />
>>> sqrt(4)<br />
2.0<br />
>>> scope['sqrt']<br />
1<br />
As you can see, the potentially destructive code does not overwrite the sqrt function; the<br />
function works just like it should, and the sqrt variable resulting from the exec’ed assignment<br />
is available from the scope.<br />
Note that if you try <strong>to</strong> print out scope, you see that it contains a lot of stuff because the<br />
dictionary called __builtins__ is au<strong>to</strong>matically added and contains all built-in functions and<br />
values:<br />
>>> len(scope)<br />
2<br />
>>> scope.keys()<br />
['sqrt', '__builtins__']<br />
eval<br />
A built-in function that is similar <strong>to</strong> exec is eval (for “evaluate”). Just as exec executes a series<br />
of <strong>Python</strong> statements, eval evaluates a <strong>Python</strong> expression (written in a string) and returns the