Catalog
Use *args and **kwargs To call a function
When to use them ?
generator (Generators)
Iteratable object (Iterable)
iterator (Iterator)
iteration (Iteration)
generator (Generators)
Now we're going to see how to use *args and **kwargs To call a function . hypothesis , You have this little function :
def test_args_kwargs(arg1, arg2, arg3):
print("arg1:", arg1)
print("arg2:", arg2)
print("arg3:", arg3)
You can use *args or **kwargs To pass parameters to this small function . Here's how to do it :
# use first *args
args = ("two", 3, 5)
test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5
# Now use **kwargs:
kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}
test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3
Standard parameters and *args、**kwargs In the order of use
So if you want to use all three parameters in a function at the same time , This is the order :
some_func(fargs, *args, **kwargs)
It really depends on your needs .
The most common use case is when writing function decorators ( It will be discussed in another chapter ).
In addition, it can also be used to make monkey patches (monkey patching). Monkey patch means when the program is running (runtime) Modify some code .
For example , You have a class , There's a man in it called get_info The function of will call a API And return the corresponding data . If we want to test it , You can put API Call to replace with some test data . example
Such as :
import someclass
def get_info(self, *args):
return "Test data"
someclass.get_info = get_info
I'm sure you can also imagine some other use cases .
First we need to understand iterators (iterators). According to Wikipedia , An iterator is a container that a programmer can traverse ( Especially the list ) The object of . However , When an iterator iterates over and reads the data elements of a container , Does not perform an iteration . You may be a little dizzy , Let's do a slow motion . In other words, there are three parts :
Iteratable object (Iterable)
iterator (Iterator)
iteration (Iteration)
These parts are related to each other . We'll discuss them first , Then we'll talk about generators (generators).
Python Any object in , As long as it defines... That can return an iterator __iter__ Method , Or it defines a that can support subscript indexes __getitem__ Method ( These double underlined methods are fully explained in other chapters ), So it's an iterative object . In short , An iteratable object is any object that can provide an iterator . What is an iterator ?
Any object , As long as it's defined next(Python2) perhaps __next__ Method , It's just an iterator . It's that simple . Now let's understand iteration (iteration)
In simple words , It is from somewhere like a list ) The process of extracting an element . When we use a loop to traverse something , The process itself is called iteration . Now that we have a basic understanding of these terms , Let's start to understand generators .
Generator is also an iterator , But you can only iterate over it once . This is because they don't store all the values in memory , Instead, values are generated at run time . You use them through traversal , Or use one “for” loop , Or pass them to any function and structure that can be iterated . Most of the time, generators are implemented as functions . However , They do not return a value , It is yield( Translation for the time being “ Born ”) A value . Here is a simple example of a generator function :
def generator_function():
for i in range(10):
yield i
for item in generator_function():
print(item)
This case is not very practical . The best scenario for the generator is : You don't want to allocate all the computed result sets to memory at the same time , In particular, the result set also contains loops .
translator's note : Doing so will consume a lot of resources
many Python 2 The standard library functions in will return a list , and Python 3 Have been modified to return to the generator , Because the generator uses less resources .
Here is a generator for calculating Fibonacci sequence :
# generator version
def fibon(n):
a = b = 1
for i in range(n):
yield a
a, b = b, a + b
# Now we can use it like this
for x in fibon(1000000):
print(x)
In this way , We don't have to worry about using a lot of resources . However , If we did this before :
def fibon(n):
a = b = 1
result = []
for i in range(n):
result.append(a)
a, b = b, a + b
return result
This may occur when calculating large input parameters , Use up all the resources . We have already discussed the generator using an iteration , But we haven't tested . You need to know one more thing before testing Python Built in functions :next(). It allows us to get the next element of a sequence . Let's verify our understanding :
def generator_function():
for i in range(3):
yield i
gen = generator_function()
print(next(gen))
# Output: 0
print(next(gen))
# Output: 1
print(next(gen))
# Output: 2
print(next(gen))
# Output: Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# StopIteration
We can see , stay yield After dropping all the values ,next() Triggered a StopIteration It's abnormal . Basically, this anomaly tells us , All values have been yield Finished . You may wonder , Why are we using for There is no such exception in the loop ? Ah , The answer is simple .for The loop will automatically catch this exception and stop calling next(). Do you know Python Some built-in data types in also support iteration ? Let's go and have a look :
my_string = "Yasoob"
next(my_string)
# Output: Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: str object is not an iterator
ok , This is not what we expected . This anomaly says that str Object is not an iterator . Yes , this is it ! It's an iterative object , Instead of an iterator . This means that it supports iterations , But we can't iterate on it directly . So how can we iterate over it ? It's time to learn another built-in function ,iter. It will return an iterator object based on an iteratable object . Here's how we use it :
my_string = "Yasoob"
my_iter = iter(my_string)
next(my_iter)
# Output: 'Y'
It's much better now . I'm sure you've fallen in love with learning builder . Remember that , Want to master this concept completely , You have to use it . Make sure you follow this pattern , And use the generator whenever it makes sense to you . You will never be disappointed !