当前位置:   article > 正文

chapter 8 functions

chapter 8 functions

Defining a Function

def greet_user(): 
	"""Display a simple greeting.""" 
	print("Hello!") 
	
greet_user()
————————————————————
Hello!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • The first line uses the keyword def to inform Python that you’re defining a function. This is the function definition, which tells Python the name of the function and, if applicable, what kind of information the function needs to do its job. The parentheses hold that information.
  • Any indented lines that follow def greet_user(): make up the body of the function. The text on the second line is a comment called a docstring, which describes what the function does. When Python generates documentation for the functions in your programs, it looks for a string immediately after the function’s definition. These strings are usually enclosed in triple quotes, which lets you write multiple lines.
  • When you want to use this function, you have to call it. A function call tells Python to execute the code in the function. To call a function, you write the name of the function, followed by any necessary information in parentheses.

Passing Information to a Function

def greet_user(username): 
	"""Display a simple greeting.""" 
	print(f"Hello, {username.title()}!") 
greet_user('jesse')
——————————————————————————————————————
Hello, Jesse!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • By adding username here, you allow the function to accept any value of username you specify. The function now expects you to provide a value for username each time you call it. When you call greet_user(), you can pass it a name, such as ‘jesse’, inside the parentheses
  • Entering greet_user(‘jesse’) calls greet_user() and gives the function the information it needs to execute the print() call. The function accepts the name you passed it and displays the greeting for that name

Arguments and Parameters

  • The variable username in the definition of greet_user() is an example of a parameter, a piece of information the function needs to do its job. The value ‘jesse’ in greet_user(‘jesse’) is an example of an argument. An argument is a piece of information that’s passed from a function call to a function. When we call the function, we place the value we want the function to work with in parentheses. In this case the argument ‘jesse’ was passed to the function greet_user(), and the value was assigned to the parameter username.
  • People sometimes speak of arguments and parameters interchangeably. Don’t be surprised if you see the variables in a function definition referred to as arguments or the variables in a function call referred to as parameters.

Passing Arguments

  • Because a function definition can have multiple parameters, a function call may need multiple arguments. You can pass arguments to your functions in a number of ways. You can use positional arguments, which need to be in the same order the parameters were written; keyword arguments, where each argument consists of a variable name and a value; and lists and dictionaries of values.

Positional Arguments

  • When you call a function, Python must match each argument in the function call with a parameter in the function definition. The simplest way to do this is based on the order of the arguments provided. Values matched up this way are called positional arguments.
def describe_pet(animal_type, pet_name): 
	"""Display information about a pet.""" 
	print(f"\nI have a {animal_type}.") 
	print(f"My {animal_type}'s name is {pet_name.title()}.") 2 

describe_pet('hamster', 'harry')
_____________________________________
I have a hamster. 
My hamster's name is Harry.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Multiple Function Calls

  • You can call a function as many times as needed. Describing a second, different pet requires just one more call to describe_pet():
def describe_pet(animal_type, pet_name): 
	"""Display information about a pet.""" 
	print(f"\nI have a {animal_type}.") 
	print(f"My {animal_type}'s name is {pet_name.title()}.") 

describe_pet('hamster', 'harry') 
describe_pet('dog', 'willie')
_________________________________
I have a hamster. 
My hamster's name is Harry.
I have a dog. 
My dog's name is Willie.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • Calling a function multiple times is a very efficient way to work. The code describing a pet is written once in the function. Then, anytime you want to describe a new pet, you call the function with the new pet’s information. Even if the code for describing a pet were to expand to 10 lines, you could still describe a new pet in just one line by calling the function again

Order Matters in Positional Arguments

def describe_pet(animal_type, pet_name): 
	"""Display information about a pet.""" 
	print(f"\nI have a {animal_type}.") 
	print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet('harry', 'hamster')
___________________________________
I have a harry. 
My harry's name is Hamster.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • If you get funny results like this, check to make sure the order of the arguments in your function call matches the order of the parameters in the function’s definition.

Keyword Arguments

  • A keyword argument is a name-value pair that you pass to a function. You directly associate the name and the value within the argument, so when you pass the argument to the function, there’s no confusion (you won’t end up with a harry named Hamster). Keyword arguments free you from having to worry about correctly ordering your arguments in the function call, and they clarify the role of each value in the function call.
def describe_pet(animal_type, pet_name): 
	"""Display information about a pet.""" 
	print(f"\nI have a {animal_type}.") 
	print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet(animal_type='hamster', pet_name='harry')
_________________________________________________

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • The function describe_pet() hasn’t changed. But when we call the function, we explicitly tell Python which parameter each argument should be matched with. When Python reads the function call, it knows to assign the argument ‘hamster’ to the parameter animal_type and the argument ‘harry’ to pet_name. The output correctly shows that we have a hamster named Harry.
  • When you use keyword arguments, be sure to use the exact names of the parameters in the function’s definition.

Default Values

  • When writing a function, you can define a default value for each parameter. If an argument for a parameter is provided in the function call, Python uses the argument value. If not, it uses the parameter’s default value. So when you define a default value for a parameter, you can exclude the corresponding argument you’d usually write in the function call. Using default values can simplify your function calls and clarify the ways your functions are typically used.
def describe_pet(pet_name, animal_type='dog'): 
	"""Display information about a pet.""" 
	print(f"\nI have a {animal_type}.") 
	print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet(pet_name='willie')
_________________________________
I have a dog. 
My dog's name is Willie.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • Note that the order of the parameters in the function definition had to be changed. Because the default value makes it unnecessary to specify a type of animal as an argument, the only argument left in the function call is the pet’s name. Python still interprets this as a positional argument, so if the function is called with just a pet’s name, that argument will match up with the first parameter listed in the function’s definition. This is the reason the first parameter needs to be pet_name.
  • When you use default values, any parameter with a default value needs to be listed after all the parameters that don’t have default values. This allows Python to continue interpreting positional arguments correctly.

Equivalent Function Calls

  • Because positional arguments, keyword arguments, and default values can all be used together, you’ll often have several equivalent ways to call a function.
  • With this definition, an argument always needs to be provided for pet_name, and this value can be provided using the positional or keyword format. If the animal being described is not a dog, an argument for animal_type must be included in the call, and this argument can also be specified using the positional or keyword format.
def describe_pet(pet_name, animal_type='dog'):
_________________________________
# A dog named Willie. 
describe_pet('willie') 
describe_pet(pet_name='willie') 
# A hamster named Harry. 
describe_pet('harry', 'hamster') 
describe_pet(pet_name='harry', animal_type='hamster') describe_pet(animal_type='hamster', pet_name='harry')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Each of these function calls would have the same output as the previous examples.
  • It doesn’t really matter which calling style you use. As long as your function calls produce the output you want, just use the style you find easiest to understand.

Avoiding Argument Errors

  • When you start to use functions, don’t be surprised if you encounter errors about unmatched arguments. Unmatched arguments occur when you provide fewer or more arguments than a function needs to do its work.
  • Python is helpful in that it reads the function’s code for us and tells us the names of the arguments we need to provide. This is another motivation for giving your variables and functions descriptive names. If you do, Python’s error messages will be more useful to you and anyone else who might use your code.
  • If you provide too many arguments, you should get a similar traceback that can help you correctly match your function call to the function definition

Return Values

  • A function doesn’t always have to display its output directly. Instead, it can process some data and then return a value or set of values. The value the function returns is called a return value. The return statement takes a value from inside a function and sends it back to the line that called the function. Return values allow you to move much of your program’s grunt work into functions, which can simplify the body of your program.

Returning a Simple Value

def get_formatted_name(first_name, last_name): 
	"""Return a full name, neatly formatted.""" 
	full_name = f"{first_name} {last_name}" 
	return full_name.title() 
musician = get_formatted_name('jimi', 'hendrix') 
print(musician)
_______________________________
Jimi Hendrix
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • The definition of get_formatted_name() takes as parameters a first and last name. The function combines these two names, adds a space between them, and assigns the result to full_name . The value of full_name is converted to title case, and then returned to the calling line
  • When you call a function that returns a value, you need to provide a variable that the return value can be assigned to. In this case, the returned value is assigned to the variable musician . The output shows a neatly formatted name made up of the parts of a person’s name:

Making an Argument Optional

  • Sometimes it makes sense to make an argument optional, so that people using the function can choose to provide extra information only if they want to. You can use default values to make an argument optional.
def get_formatted_name(first_name, middle_name, last_name): 
	"""Return a full name, neatly formatted.""" 
	full_name = f"{first_name} {middle_name} {last_name}" 
	return full_name.title() 

musician = get_formatted_name('john', 'lee', 'hooker') 
print(musician)
______________________________
John Lee Hooker
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • But middle names aren’t always needed, and this function as written would not work if you tried to call it with only a first name and a last name. To make the middle name optional, we can give the middle_name argument an empty default value and ignore the argument unless the user provides a value. To make get_formatted_name() work without a middle name, we set the default value of middle_name to an empty string and move it to the end of the list of parameters
def get_formatted_name(first_name, last_name, middle_name=''): 
	"""Return a full name, neatly formatted.""" 
	if middle_name: 
		full_name = f"{first_name} {middle_name} {last_name}" 
	else: 
		full_name = f"{first_name} {last_name}" 
		return full_name.title() 

musician = get_formatted_name('jimi', 'hendrix') 
print(musician)  
musician = get_formatted_name('john', 'hooker', 'lee') 
print(musician)
# 注意:返回值需要赋值给变量后再读取到函数的返回值,如果直接打印函数的话,那么打印出来的函数的地址
_____________________________________________________
Jimi Hendrix 
John Lee Hooker
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • In this example, the name is built from three possible parts. Because there’s always a first and last name, these parameters are listed first in the function’s definition. The middle name is optional, so it’s listed last in the definition, and its default value is an empty string.
  • In the body of the function, we check to see if a middle name has been provided. Python interprets non-empty strings as True, so the conditional test if middle_name evaluates to True if a middle name argument is in the function call . If a middle name is provided, the first, middle, and last names are combined to form a full name. This name is then changed to title case and returned to the function call line, where it’s assigned to the variable musician and printed. If no middle name is provided, the empty string fails the if test and the else block runs . The full name is made with just a first and last name, and the formatted name is returned to the calling line where it’s assigned to musician and printed.
  • Calling this function with a first and last name is straightforward. If we’re using a middle name, however, we have to make sure the middle name is the last argument passed so Python will match up the positional arguments correctly
  • Optional values allow functions to handle a wide range of use cases while letting function calls remain as simple as possible

Returning a Dictionary

  • A function can return any kind of value you need it to, including more complicated data structures like lists and dictionaries
def build_person(first_name, last_name): 
	"""Return a dictionary of information about a person.""" 
	person = {'first': first_name, 'last': last_name} 
	return person 
musician = build_person('jimi', 'hendrix')  
print(musician)
——————————————————————————————————————————
{'first': 'jimi', 'last': 'hendrix'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • The function build_person() takes in a first and last name, and puts these values into a dictionary . The value of first_name is stored with the key ‘first’, and the value of last_name is stored with the key ‘last’. Then, the entire dictionary representing the person is returned . The return value is printed  with the original two pieces of textual information now stored in a dictionary
  • This function takes in simple textual information and puts it into a more meaningful data structure that lets you work with the information beyond just printing it.
def build_person(first_name, last_name, age=None): 
	"""Return a dictionary of information about a person.""" 
	person = {'first': first_name, 'last': last_name} 
	if age: 
		person['age'] = age 
	return person 

musician = build_person('jimi', 'hendrix', age=27) 
print(musician)
————————————————————————————————————————————
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • We add a new optional parameter age to the function definition and assign the parameter the special value None, which is used when a variable has no specific value assigned to it. You can think of None as a placeholder value. In conditional tests, None evaluates to False. If the function call includes a value for age, that value is stored in the dictionary. This function always stores a person’s name, but it can also be modified to store any other information you want about a person.

Using a Function with a while Loop

  • You can use functions with all the Python structures you’ve learned about so far.
def get_formatted_name(first_name, last_name): 
	"""Return a full name, neatly formatted.""" 
	full_name = f"{first_name} {last_name}" 
	return full_name.title() 
# This is an infinite loop! 
while True: 
	print("\nPlease tell me your name:") 
	f_name = input("First name: ") 
	l_name = input("Last name: ") 
	formatted_name = get_formatted_name(f_name, l_name) 
	print(f"\nHello, {formatted_name}!")
————————————————————————————————————————————————————————————

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • For this example, we use a simple version of get_formatted_name() that doesn’t involve middle names. The while loop asks the user to enter their name, and we prompt for their first and last name separately .
  • But there’s one problem with this while loop: We haven’t defined a quit condition. Where do you put a quit condition when you ask for a series of inputs? We want the user to be able to quit as easily as possible, so each prompt should offer a way to quit. The break statement offers a straightforward way to exit the loop at either prompt
def get_formatted_name(first_name, last_name): 
	"""Return a full name, neatly formatted.""" 
	full_name = f"{first_name} {last_name}" 
	return full_name.title() 
while True: 
	print("\nPlease tell me your name:") 
	print("(enter 'q' at any time to quit)") 
	f_name = input("First name: ") 
	if f_name == 'q': 
		break 
	l_name = input("Last name: ") 
	if l_name == 'q': 
		break 
	formatted_name = get_formatted_name(f_name, l_name)
	print(f"\nHello, {formatted_name}!")
————————————————————————————————————————————————
Please tell me your name: 
(enter 'q' at any time to quit) 
First name: eric 
Last name: matthes 
Hello, Eric Matthes! 

Please tell me your name: 
(enter 'q' at any time to quit) 
First name: q
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • We add a message that informs the user how to quit, and then we break out of the loop if the user enters the quit value at either prompt. Now the program will continue greeting people until someone enters q for either name

Passing a List

  • You’ll often find it useful to pass a list to a function, whether it’s a list of names, numbers, or more complex objects, such as dictionaries. When you pass a list to a function, the function gets direct access to the contents of the list
def greet_users(names): 
	"""Print a simple greeting to each user in the list.""" 
	for name in names: msg = f"Hello, {name.title()}!" 
	print(msg) 
usernames = ['hannah', 'ty', 'margot'] 
greet_users(usernames)
————————————————————————
Hello, Hannah! 
Hello, Ty! 
Hello, Margot!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • Say we have a list of users and want to print a greeting to each. The following example sends a list of names to a function called greet_users(), which greets each person in the list individually
  • We define greet_users() so it expects a list of names, which it assigns to the parameter names. The function loops through the list it receives and prints a greeting to each user. Outside of the function, we define a list of users and then pass the list usernames to greet_users() in the function call

Modifying a List in a Function

  • When you pass a list to a function, the function can modify the list. Any changes made to the list inside the function’s body are permanent, allowing you to work efficiently even when you’re dealing with large amounts of data.
  • Consider a company that creates 3D printed models of designs that users submit. Designs that need to be printed are stored in a list, and after being printed they’re moved to a separate list.
# Start with some designs that need to be printed. 
unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron']
completed_models = [] 

# Simulate printing each design, until none are left. 
# Move each design to completed_models after printing. 
while unprinted_designs: 
	current_design = unprinted_designs.pop() 
	print(f"Printing model: {current_design}") 
	completed_models.append(current_design) 

# Display all completed models. 
print("\nThe following models have been printed:") 
for completed_model in completed_models: 
	print(completed_model)
————————————————————————————————
Printing model: dodecahedron 
Printing model: robot pendant 
Printing model: phone case 

The following models have been printed: 
dodecahedron 
robot pendant 
phone case
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • This program starts with a list of designs that need to be printed and an empty list called completed_models that each design will be moved to after it has been printed. As long as designs remain in unprinted_designs, the while loop simulates printing each design by removing a design from the end of the list, storing it in current_design, and displaying a message that the current design is being printed. It then adds the design to the list of completed models. When the loop is finished running, a list of the designs that have been printed is displayed
  • We can reorganize this code by writing two functions, each of which does one specific job. Most of the code won’t change; we’re just structuring it more carefully. The first function will handle printing the designs, and the second will summarize the prints that have been made
def print_models(unprinted_designs, completed_models): 
	""" 
	Simulate printing each design, until none are left.
	Move each design to completed_models after printing. 
	"""
	while unprinted_designs: 
		current_design = unprinted_designs.pop() 
		print(f"Printing model: {current_design}") 
		completed_models.append(current_design)

def show_completed_models(completed_models): 
	"""Show all the models that were printed.""" 
	print("\nThe following models have been printed:") 
	for completed_model in completed_models: 
		print(completed_model) 

unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron'] completed_models = [] 

print_models(unprinted_designs, completed_models) show_completed_models(completed_models)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • We define the function print_models() with two parameters: a list of designs that need to be printed and a list of completed models . Given these two lists, the function simulates printing each design by emptying the list of unprinted designs and filling up the list of completed models. We then define the function show_completed_models() with one parameter: the list of completed models . Given this list, show_completed_models() displays the name of each model that was printed.
  • We set up a list of unprinted designs and an empty list that will hold the completed models. Then, because we’ve already defined our two functions, all we have to do is call them and pass them the right arguments. We call print_models() and pass it the two lists it needs; as expected, print_models() simulates printing the designs. Then we call show_completed_models() and pass it the list of completed models so it can report the models that have been printed. The descriptive function names allow others to read this code and understand it, even without comments.
  • This example also demonstrates the idea that every function should have one specific job. The first function prints each design, and the second displays the completed models. This is more beneficial than using one function to do both jobs. If you’re writing a function and notice the function is doing too many different tasks, try to split the code into two functions. Remember that you can always call a function from another function, which can be helpful when splitting a complex task into a series of steps.

Preventing a Function from Modifying a List

  • Sometimes you’ll want to prevent a function from modifying a list。For example, say that you start with a list of unprinted designs and write a function to move them to a list of completed models, as in the previous example. You may decide that even though you’ve printed all the designs, you want to keep the original list of unprinted designs for your records. But because you moved all the design names out of unprinted_designs, the list is now empty, and the empty list is the only version you have; the original is gone. In this case, you can address this issue by passing the function a copy of the list, not the original. Any changes the function makes to the list will affect only the copy, leaving the original list intact.
  • You can send a copy of a list to a function like this:
function_name(list_name[:])
  • 1
  • The slice notation [:] makes a copy of the list to send to the function. If we didn’t want to empty the list of unprinted designs in printing_models.py, we could call print_models() like this:
print_models(unprinted_designs[:], completed_models)
  • 1
  • The function print_models() can do its work because it still receives the names of all unprinted designs. But this time it uses a copy of the original unprinted designs list, not the actual unprinted_designs list. The list completed _models will fill up with the names of printed models like it did before, but the original list of unprinted designs will be unaffected by the function.
  • Even though you can preserve the contents of a list by passing a copy of it to your functions, you should pass the original list to functions unless you have a specific reason to pass a copy. It’s more efficient for a function to work with an existing list, because this avoids using the time and memory needed to make a separate copy. This is especially true when working with large lists.

Passing an Arbitrary Number of Arguments

  • Sometimes you won’t know ahead of time how many arguments a function needs to accept. Fortunately, Python allows a function to collect an arbitrary number of arguments from the calling statement.
def make_pizza(*toppings): 
	"""Print the list of toppings that have been requested.""" 
	print(toppings) 

make_pizza('pepperoni') 
make_pizza('mushrooms', 'green peppers', 'extra cheese')
___________________________________________________
('pepperoni',) 
('mushrooms', 'green peppers', 'extra cheese')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • The asterisk in the parameter name *toppings tells Python to make a tuple called toppings, containing all the values this function receives. The print() call in the function body produces output showing that Python can handle a function call with one value and a call with three values. It treats the different calls similarly. Note that Python packs the arguments into a tuple, even if the function receives only one value
def make_pizza(*toppings): 
	"""Summarize the pizza we are about to make."""
	print("\nMaking a pizza with the following toppings:") 
	for topping in toppings: 
		print(f"- {topping}") 
	
make_pizza('pepperoni') 
make_pizza('mushrooms', 'green peppers', 'extra cheese')
_____________________________
Making a pizza with the following toppings: 
- pepperoni 

Making a pizza with the following toppings:
- mushrooms 
- green peppers 
- extra cheese
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • This syntax works no matter how many arguments the function receives.

Mixing Positional and Arbitrary Arguments

  • If you want a function to accept several different kinds of arguments, the parameter that accepts an arbitrary number of arguments must be placed last in the function definition. Python matches positional and keyword arguments first and then collects any remaining arguments in the final parameter.
def make_pizza(size, *toppings): 
	"""Summarize the pizza we are about to make.""" 
	print(f"\nMaking a {size}-inch pizza with the following toppings:") 
	for topping in toppings: 
		print(f"- {topping}") 

make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
______________________________________________________________
Making a 16-inch pizza with the following toppings: 
- pepperoni

Making a 12-inch pizza with the following toppings: 
- mushrooms 
- green peppers 
- extra cheese
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • In the function definition, Python assigns the first value it receives to the parameter size. All other values that come after are stored in the tuple toppings. The function calls include an argument for the size first, followed by as many toppings as needed.
  • You’ll often see the generic parameter name *args, which collects arbitrary positional arguments like this.

Using Arbitrary Keyword Arguments

  • Sometimes you’ll want to accept an arbitrary number of arguments, but you won’t know ahead of time what kind of information will be passed to the function. In this case, you can write functions that accept as many key-value pairs as the calling statement provides.
def build_profile(first, last, **user_info): 
	"""Build a dictionary containing everything we know about a user.""" 
	user_info['first_name'] = first 
	user_info['last_name'] = last 
	return user_info 

user_profile = build_profile('albert', 'einstein', 
							 location='princeton', 
							 field='physics') 
print(user_profile)
——————————————————————————————
{'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • The definition of build_profile() expects a first and last name, and then it allows the user to pass in as many name-value pairs as they want. The double asterisks before the parameter **user_info cause Python to create a dictionary called user_info containing all the extra name-value pairs the function receives. Within the function, you can access the key-value pairs in user_info just as you would for any dictionary.
  • In the body of build_profile(), we add the first and last names to the user_info dictionary because we’ll always receive these two pieces of information from the user 1, and they haven’t been placed into the dictionary yet. Then we return the user_info dictionary to the function call line.
  • We call build_profile(), passing it the first name ‘albert’, the last name ‘einstein’, and the two key-value pairs location=‘princeton’ and field=‘physics’.
  • The returned dictionary contains the user’s first and last names and, in this case, the location and field of study as well. The function will work no matter how many additional key-value pairs are provided in the function call.
  • You can mix positional, keyword, and arbitrary values in many different ways when writing your own functions. It’s useful to know that all these argument types exist because you’ll see them often when you start reading other people’s code. It takes practice to use the different types correctly and to know when to use each type. For now, remember to use the simplest approach that gets the job done. As you progress, you’ll learn to use the most efficient approach each time.
  • You’ll often see the parameter name **kwargs used to collect nonspecific keyword arguments.

Storing Your Functions in Modules

  • One advantage of functions is the way they separate blocks of code from your main program. When you use descriptive names for your functions, your programs become much easier to follow. You can go a step further by storing your functions in a separate file called a module and then importing that module into your main program. An import statement tells Python to make the code in a module available in the currently running program file.
  • Storing your functions in a separate file allows you to hide the details of your program’s code and focus on its higher-level logic. It also allows you to reuse functions in many different programs. When you store your functions in separate files, you can share those files with other programmers without having to share your entire program. Knowing how to import functions also allows you to use libraries of functions that other programmers have written.

Importing an Entire Module

  • To start importing functions, we first need to create a module. A module is a file ending in .py that contains the code you want to import into your program.
def make_pizza(size, *toppings): 
	"""Summarize the pizza we are about to make.""" 
	print(f"\nMaking a {size}-inch pizza with the following toppings:") 
	for topping in toppings: 
		print(f"- {topping}")
_____________________________________
import pizza 
pizza.make_pizza(16, 'pepperoni') 
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
_______________________________
Making a 16-inch pizza with the following toppings: 
- pepperoni 

Making a 12-inch pizza with the following toppings: 
- mushrooms 
- green peppers 
- extra cheese
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • When Python reads this file, the line import pizza tells Python to open the file pizza.py and copy all the functions from it into this program. You don’t actually see code being copied between files because Python copies the code behind the scenes, just before the program runs. All you need to know is that any function defined in pizza.py will now be available in making_pizzas.py.
  • To call a function from an imported module, enter the name of the module you imported, pizza, followed by the name of the function, make _pizza(), separated by a dot . This code produces the same output as the original program that didn’t import a module
  • This first approach to importing, in which you simply write import followed by the name of the module, makes every function from the module available in your program. If you use this kind of import statement to import an entire module named module_name.py, each function in the module is available through the following syntax
module_name.function_name()
  • 1

Importing Specific Functions

  • You can also import a specific function from a module. Here’s the general syntax for this approach:
from module_name import function_name
  • 1
  • You can import as many functions as you want from a module by separating each function’s name with a comma:
from module_name import function_0, function_1, function_2
  • 1
  • The making_pizzas.py example would look like this if we want to import just the function we’re going to use:
from pizza import make_pizza 
make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
  • 1
  • 2
  • 3
  • With this syntax, you don’t need to use the dot notation when you call a function. Because we’ve explicitly imported the function make_pizza() in the import statement, we can call it by name when we use the function.

Using as to Give a Function an Alias

  • If the name of a function you’re importing might conflict with an existing name in your program, or if the function name is long, you can use a short, unique alias—an alternate name similar to a nickname for the function. You’ll give the function this special nickname when you import the function.
from pizza import make_pizza as mp 
mp(16, 'pepperoni') 
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
  • 1
  • 2
  • 3
  • The import statement shown here renames the function make_pizza() to mp() in this program. Anytime we want to call make_pizza() we can simply write mp() instead, and Python will run the code in make_pizza() while avoiding any confusion with another make_pizza() function you might have written in this program file
  • The general syntax for providing an alias is:
from module_name import function_name as fn
  • 1

Using as to Give a Module an Alias

  • You can also provide an alias for a module name. Giving a module a short alias, like p for pizza, allows you to call the module’s functions more quickly. Calling p.make_pizza() is more concise than calling pizza.make_pizza():
import pizza as p 
p.make_pizza(16, 'pepperoni') 
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
  • 1
  • 2
  • 3
  • The module pizza is given the alias p in the import statement, but all of the module’s functions retain their original names. Calling the functions by writing p.make_pizza() is not only more concise than pizza.make_pizza(), but it also redirects your attention from the module name and allows you to focus on the descriptive names of its functions. These function names, which clearly tell you what each function does, are more important to the readability of your code than using the full module name.
  • The general syntax for this approach is:
import module_name as mn
  • 1

Importing All Functions in a Module

  • You can tell Python to import every function in a module by using the asterisk (*) operator:
from pizza import * 
make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
  • 1
  • 2
  • 3
  • The asterisk in the import statement tells Python to copy every function from the module pizza into this program file. Because every function is imported, you can call each function by name without using the dot notation. However, it’s best not to use this approach when you’re working with larger modules that you didn’t write: if the module has a function name that matches an existing name in your project, you can get unexpected results. Python may see several functions or variables with the same name, and instead of importing all the functions separately, it will overwrite the functions.
  • The best approach is to import the function or functions you want, or import the entire module and use the dot notation. This leads to clear code that’s easy to read and understand. I include this section so you’ll recognize import statements like the following when you see them in other people’s code:
from module_name import *
  • 1

Styling Functions

  • You need to keep a few details in mind when you’re styling functions. Functions should have descriptive names, and these names should use lowercase letters and underscores. Descriptive names help you and others understand what your code is trying to do. Module names should use these conventions as well.
  • Every function should have a comment that explains concisely what the function does. This comment should appear immediately after the function definition and use the docstring format. In a well-documented function, other programmers can use the function by reading only the description in the docstring. They should be able to trust that the code works as described, and as long as they know the name of the function, the arguments it needs, and the kind of value it returns, they should be able to use it in their programs.
  • If you specify a default value for a parameter, no spaces should be used on either side of the equal sign:
def function_name(parameter_0, parameter_1='default value')
  • 1
  • The same convention should be used for keyword arguments in function calls:
function_name(value_0, parameter_1='value')
  • 1
  • PEP 8 (https://www.python.org/dev/peps/pep-0008) recommends that you limit lines of code to 79 characters so every line is visible in a reasonably sized editor window. If a set of parameters causes a function’s definition to be longer than 79 characters, press ENTER after the opening parenthesis on the definition line. On the next line, press the TAB key twice to separate the list of arguments from the body of the function, which will only be indented one level.
  • Most editors automatically line up any additional lines of arguments to match the indentation you have established on the first line
def function_name( 
		parameter_0, parameter_1, parameter_2, 
		parameter_3, parameter_4, parameter_5): 
	function body...
  • 1
  • 2
  • 3
  • 4
  • If your program or module has more than one function, you can separate each by two blank lines to make it easier to see where one function ends and the next one begins.
  • All import statements should be written at the beginning of a file. The only exception is if you use comments at the beginning of your file to describe the overall program.
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/237422
推荐阅读
相关标签
  

闽ICP备14008679号