ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 17.04.2021

Просмотров: 3747

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

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


background image

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


background image

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

print

(

’*************’

)

18

print

(

"s = {0:s}"

.

format(s))

19

print

(

"v = {0:5.2f}"

.

format(v))

20

print

(

"t = {0:s}"

.

format(t))

21

print

(

"l = {0:s}"

.

format(l))

22

print

(

"a = "

),

# comma suppresses line feed

23

print

(a)

24

print

(

’*************’

)

25

print

(

’*call "test"*’

)

26

27

s1, v1, t1, l1, a1

=

test(s, v, t, l, a)

28

29

print

(

’*************’

)

30

print

(

"s1 = {0:s}"

.

format(s1))

31

print

(

"v1 = {0:5.2f}"

.

format(v1))

32

print

(

"t1 = {0:s}"

.

format(t1))

33

print

(

"l1 = {0:s}"

.

format(l1))

34

print

(

"a1 = "

),

35

print

(a1)

36

print

(

’*************’

)

37

print

(

"s = {0:s}"

.

format(s))

38

print

(

"v = {0:5.2f}"

.

format(v))

39

print

(

"t = {0:s}"

.

format(t))

40

print

(

"l = {0:s}"

.

format(l))

41

print

(

"a = "

),

# comma suppresses line feed

42

print

(a)

43

print

(

’*************’

)

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


background image

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


background image

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