ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 17.04.2021
Просмотров: 3747
Скачиваний: 3

Introduction to Python for Science, Release 0.9.23
7.1.6 Passing data to and from functions
Functions are like mini-programs within the larger programs that call them. Each function
has a set of variables with certain names that are to some degree or other isolated from
the calling program. We shall get more specific about just how isolated those variables
are below, but before we do, we introduce the concept of a
namespace
. Each function
has its own namespace, which is essentially a mapping of variable names to objects, like
numerics, strings, lists, and so forth. It’s a kind of dictionary. The calling program has its
own namespace, distinct from that of any functions it calls. The distinctiveness of these
namespaces plays an important role in how functions work, as we shall see below.
Variables and arrays created entirely within a function
An important feature of functions is that variables and arrays created
entirely within
a
function cannot be seen by the program that calls the function unless the variable or array
is explicitly passed to the calling program in the
return
statement. This is important
because it means you can create and manipulate variables and arrays, giving them any
name you please, without affecting any variables or arrays outside the function, even if
the variables and arrays inside and outside a function share the same name.
To see what how this works, let’s rewrite our program to plot the sinc function using the
sinc function definition that uses the
where
function.
1
def
sinc
(x):
2
z
=
np
.
where(x
==
0.0
,
1.0
, np
.
sin(x)
/
x)
3
return
z
4
5
import
numpy
as
np
6
import
matplotlib.pyplot
as
plt
7
8
x
=
np
.
linspace(
-
10
,
10
,
256
)
9
y
=
sinc(x)
10
11
plt
.
plot(x, y)
12
plt
.
axhline(color
=
"gray"
, zorder
=-
1
)
13
plt
.
axvline(color
=
"gray"
, zorder
=-
1
)
14
plt
.
show()
Running this program produces a plot like the plot of sinc shown in the previous section.
Notice that the array variable
z
is only defined within the function definition of sinc. If
we run the program from the IPython terminal, it produces the plot, of course. Then if we
ask IPython to print out the arrays,
x
,
y
, and
z
, we get some interesting and informative
results, as shown below.
7.1. User-defined functions
125

Introduction to Python for Science, Release 0.9.23
In [15]:
run sinc3
.
py
In [16]:
x
Out[16]:
array([
-
10.
,
-
9.99969482
,
-
9.99938964
,
...
,
9.99938964,
9.99969482,
10.
])
In [17]:
y
Out[17]:
array([
-
0.05440211
,
-
0.05437816
,
-
0.0543542
,
...
,
-0.0543542 , -0.05437816, -0.05440211])
In [18]:
z
---------------------------------------------------------
NameError
Traceback (most recent call last)
NameError: name ’z’ is not defined
When we type in
x
at the
In [16]:
prompt, IPython prints out the array
x
(some of the
output is suppressed because the array
x
has many elements); similarly for
y
. But when
we type
z
at the
In [18]:
prompt, IPython returns a
NameError
because
z
is not
defined. The IPython terminal is working in the same
namespace
as the program. But the
namespace of the sinc function is isolated from the namespace of the program that calls
it, and therefore isolated from IPython. This also means that when the sinc function ends
with
return z
, it doesn’t return the name
z
, but instead assigns the values in the array
z
to the array
y
, as directed by the main program in line 9.
Passing variables and arrays to functions: mutable and immutable objects
What happens to a variable or an array passed to a function when the variable or array
is
changed
within the function? It turns out that the answers are different depending on
whether the variable passed is a simple numeric variable, string, or tuple, or whether it
is an array or list. The program below illustrates the different ways that Python handles
single variables
vs
the way it handles lists and arrays.
1
def
test
(s, v, t, l, a):
2
s
=
"I am doing fine"
3
v
=
np
.
pi
**
2
4
t
=
(
1.1
,
2.9
)
5
l[
-
1
]
=
’end’
6
a[
0
]
=
963.2
7
return
s, v, t, l, a
8
9
import
numpy
as
np
10
126
Chapter 7. Functions

Introduction to Python for Science, Release 0.9.23
11
s
=
"How do you do?"
12
v
=
5.0
13
t
=
(
97.5
,
82.9
,
66.7
)
14
l
=
[
3.9
,
5.7
,
7.5
,
9.3
]
15
a
=
np
.
array(l)
16
17
(
’*************’
)
18
(
"s = {0:s}"
.
format(s))
19
(
"v = {0:5.2f}"
.
format(v))
20
(
"t = {0:s}"
.
format(t))
21
(
"l = {0:s}"
.
format(l))
22
(
"a = "
),
# comma suppresses line feed
23
(a)
24
(
’*************’
)
25
(
’*call "test"*’
)
26
27
s1, v1, t1, l1, a1
=
test(s, v, t, l, a)
28
29
(
’*************’
)
30
(
"s1 = {0:s}"
.
format(s1))
31
(
"v1 = {0:5.2f}"
.
format(v1))
32
(
"t1 = {0:s}"
.
format(t1))
33
(
"l1 = {0:s}"
.
format(l1))
34
(
"a1 = "
),
35
(a1)
36
(
’*************’
)
37
(
"s = {0:s}"
.
format(s))
38
(
"v = {0:5.2f}"
.
format(v))
39
(
"t = {0:s}"
.
format(t))
40
(
"l = {0:s}"
.
format(l))
41
(
"a = "
),
# comma suppresses line feed
42
(a)
43
(
’*************’
)
The function
test
has five arguments, a string
s
, a numerical variable
v
, a tuple
t
, a list
l
, and a NumPy array
a
.
test
modifies each of these arguments and then returns the
modified
s
,
v
,
t
,
l
,
a
. Running the program produces the following output.
In [17]:
run passingVars
.
py
*************
s = How do you do?
v =
5.00
t = (97.5, 82.9, 66.7)
l = [3.9, 5.7, 7.5, 9.3]
a =
[ 3.9
5.7
7.5
9.3]
7.1. User-defined functions
127

Introduction to Python for Science, Release 0.9.23
*************
*call "test"*
*************
s1 = I am doing fine
v1 =
9.87
t1 = (1.1, 2.9)
l1 = [3.9, 5.7, 7.5, ’end’]
a1 =
[ 963.2
5.7
7.5
9.3]
*************
s = How do you do?
v =
5.00
t = (97.5, 82.9, 66.7)
l = [3.9, 5.7, 7.5, ’end’]
a =
[ 963.2
5.7
7.5
9.3]
*************
The program prints out three blocks of variables separated by asterisks. The first block
merely verifies that the contents of
s
,
v
,
t
,
l
, and
a
are those assigned in lines 10-13.
Then the function
test
is called. The next block prints the output of the call to the
function
test
, namely the variables
s1
,
v1
,
t1
,
l1
, and
a1
. The results verify that the
function modified the inputs as directed by the
test
function.
The third block prints out the variables
s
,
v
,
t
,
l
, and
a
from the calling program
after
the function
test
was called. These variables served as the inputs to the function
test
.
Examining the output from the third printing block, we see that the values of the string
s
,
the numeric variable
v
, and the contents of
t
are unchanged after the function call. This
is probably what you would expect. On the other hand, we see that the list
l
and the array
a
are changed after the function call. This might surprise you! But these are important
points to remember, so important that we summarize them in two bullet points here:
• Changes to string, variable, and tuple arguments of a function within the function
do not affect their values in the calling program.
• Changes to values of elements in list and array arguments of a function within the
function are reflected in the values of the same list and array elements in the calling
function.
The point is that simple numerics, strings and tuples are immutable while lists and arrays
are mutable. Because immutable objects can’t be changed, changing them within a func-
tion creates new objects with the same name inside of the function, but the old immutable
objects that were used as arguments in the function call remain unchanged in the calling
program. On the other hand, if elements of mutable objects like those in lists or arrays are
changed, then those elements that are changed inside the function are also changed in the
calling program.
128
Chapter 7. Functions

Introduction to Python for Science, Release 0.9.23
7.2 Methods and attributes
You have already encountered quite a number of functions that are part of either NumPy
or Python or Matplotlib. But there is another way in which Python implements things that
act like functions. To understand what they are, you need to understand that variables,
strings, arrays, lists, and other such data structures in Python are not merely the numbers
or strings we have defined them to be. They are
objects
. In general, an object in Python
has associated with it a number of
attributes
and a number of specialized functions called
methods
that act on the object. How attributes and methods work with objects is best
illustrated by example.
Let’s start with the NumPy array. A NumPy array is a Python object and therefore has
associated with it a number of attributes and methods. Suppose, for example, we write
a
= random.random(10)
, which creates an array of 10 uniformly distributed random
numbers between 0 and 1. An example of an attribute of an array is the size or number of
elements in the array. An attribute of an object in Python is accessed by typing the object
name followed by a period followed by the attribute name. The code below illustrates
how to access two different attributes of an array, it’s size and its data type.
In [18]:
a
=
random
.
random(
10
)
In [19]:
a
.
size
Out[19]:
10
In [20]:
a
.
dtype
Out[20]:
dtype(
’float64’
)
Any object in Python can and in general does have a number of attributes that are accessed
in just the way demonstrated above, with a period and the attribute name following the
name of the particular object. In general, attributes involve properties of the object that
are stored by Python with the object and require no computation. Python just looks up the
attribute and returns its value.
Objects in Python also have associated with them a number of specialized functions called
methods
that act on the object. In contrast to attributes, methods generally involve Python
performing some kind of computation. Methods are accessed in a fashion similar to
attributes, by appending a period followed the method’s name, which is followed by a
pair of open-close parentheses, consistent with methods being a kind of function that acts
on the object. Often methods are used with no arguments, as methods by default act on the
object whose name they follow. In some cases. however, methods can take arguments.
Examples of methods for NumPy arrays are sorting, calculating the mean, or standard
deviation of the array. The code below illustrates a few array methods.
7.2. Methods and attributes
129