Now that we understand the distinction between object references and objects, we‘ll look at some more capabilities of function arguments. The formal function arguments specified when a function is defined with the def keyword are a comma?separated list of the argument names. These arguments can be made optional by providing default values.
Consider a function which prints a simple banner to the console. This function takes two arguments, the second of which is provided with a default value, in this case a hyphen, in a literal string. Since we‘ve given it this default value, callers can choose whether they want to pass their own value for border or use the default. Note that when we define functions using default arguments, the parameters with default arguments must come after those without defaults. Otherwise, we will get a syntax error.
Within the body of the function. We multiply our border string by the length of the message string. This shows how we can determine the number of items in a Python collection using the built?in lend function. Secondly, it shows how multiplying a string, in this case the single?character string border, by an integer results in a new string containing the original string repeated a number of times. We use that feature here to make a string equal in length to our message.
We then print the full width border, the message, and the border again. When we call our banner function, we don‘t need to supply the border string because we provided a default value. We can see that the default border of hyphens has been created. However, if we do provide an optional argument, it‘s used.
In production code, this function call is not particularly self documenting. We can improve that situation by naming the border argument at the call site. In this case, the message string is called a positional argument and the border string a keyword argument. The actual positional arguments are matched up in sequence with the formal arguments, that is by position, whereas the keyword arguments are matched by name. If we use keyword arguments for both of our parameters, we have the freedom to supply them in any order. Remember though that all keyword arguments must be specified after the positional arguments.
It‘s crucial to have an appreciation of exactly when the expression provided as a default value is evaluated. This will help you avoid a common pitfall, which frequently ensnares newcomers to Python. Let‘s examine this question closely using the Python standard library time module. We can easily get the time as a readable string by using the ctime function of the time module. Let‘s write a function, which uses a value retrieved from ctime as a default argument value. So far, so good. But notice what happens when you call show_default again a few seconds later, and again. The displayed time never progresses. Recall how we said that def is a statement that, when executed, binds a function definition to a function name? Well, the default argument expressions are evaluated only once when the def statement is executed. Normally, when the default is a simple, immutable constant, such as an integer or a string, this causes no problems. But it can be a confusing trap for the unwary that usually shows up in the form of using mutable collections as argument defaults. Let‘s take a closer look. Consider this function, which uses an empty list as a default argument. It accepts a menu, which will be a list of strings, appends the item spam to the list, and returns the modified menu. Let‘s create a simple breakfast of bacon and eggs. Naturally, we‘ll want to add Spam to it. We‘ll, do something similar for our lunch of baked beans. Nothing unexpected so far. But look what happens when you rely on the default argument by not passing an existing menu. When we append spam to the default value of the empty menu, we get just spam. Let‘s do that again. When we exercise the default argument value a second time, we get two spams, and three and four. What‘s happening here is that the empty list used for the default argument is created exactly once, when the def statement is executed. The first time we fall back on the default, this list has spam added to it. When we use the default a second time, the list still contains that item, and a second instance of spam is added to it, making two, ad infinitum, or perhaps ad nauseum would be more appropriate. The solution to this is straightforward, but perhaps not obvious. Always use immutable objects such as integers or strings for default values. Following this advice, we can solve this particular case by using the immutable None object as a sentinel. Now our function needs to check if menu is none and provide a newly constructed empty list, if so. The rest of the function behaves as before. Now, if we call the function repeatedly with no arguments, we get the same menu, one order of spam each time.
所以,请不要给默认值传参设置可变集合,避免潜在问题
而且,我们有解决办法
原文:https://www.cnblogs.com/hmlhml/p/14493442.html