Learn from the Python legend of function writing

  • 2020-04-02 14:14:45
  • OfStack

There is always more to be said about functions, so here are some tips for writing them. For the record, I did not sum up these matters. I copied them from a book named "Learning Python" and wrote them in Chinese. It can also be interpreted as originating from Learning Python but a little different.
  The & # 8226; The function is independent. It's often said don't have too much coupling. You want the function to be independent of the external thing. Arguments and return statements are the best ways to achieve this independence.
  The & # 8226; Try not to use global variables, which is also a way to keep the coupling low. Although the global variable function inside and outside of the communication, but it strengthened the function on the external dependence, often let the function of the modification and debugging more trouble.
  The & # 8226; If the parameter object is of variable type, do not modify it in the function. Of course, more often than not, the parameters passed in are ideally immutable.
  The & # 8226; The functions and objectives of the function implementation should be simplified. At the beginning of each function, there should be a short sentence stating the function's function and goal.
  The & # 8226; Function is not too large, can be small is small, according to the principle of the previous, the function of a single target, the number of code bar is small. If it feels a little big, let's see if we can break it down into a couple of functions.
  The & # 8226; Do not modify variables in another module file. This is the same principle as above, the goal is to reduce coupling.
 
Let's try recursion a little bit

I'm cautious about using recursion in python, if I can, why? On the one hand, I'm afraid that I won't be able to learn well. On the other hand, recursion not only consumes resources, but it is not as fast as the for loop in many cases.

However, as a programmer, recursion is something to understand. Here is a simple example.


>>> def newsum(lst):
...     if not lst:
...         return 0
...     else:
...         return lst[0] + newsum(lst[1:])
...
>>> newsum([1,2,3])
6

  This is a function that sums a list. Why write it yourself? Yeah, in actual programming, you don't have to write it yourself, you just write sum. Of course, I didn't determine whether the parameters passed to the function were a list composed entirely of Numbers, so if the input list contained letters, the program would look like this:


>>> newsum([1,2,3,'q'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in newsum
  File "<stdin>", line 5, in newsum
  File "<stdin>", line 5, in newsum
  File "<stdin>", line 5, in newsum
TypeError: cannot concatenate 'str' and 'int' objects

  That's the problem with this function. But, to illustrate recursion, we don't care that much. Ignore this flaw for a moment. Return LST (0)+newsum(LST [1:]). Okay, so this is recursive, calling the function itself in the function. The difference, of course, is that the parameters passed in have changed. To clear the call flow of the function, we can print out the parameters passed in each time:


>>> def newsum(lst):
...     print lst
...     if not lst:
...         return 0
...     else:
...         return lst[0] + newsum(lst[1:])
...
>>> newsum([1,2,3])
[1, 2, 3]
[2, 3]
[3]
[]
6

  So that's the recursion.

In fact, the reader may have thought that even if you don't use sum, you can use for to do the above operations.


>>> lst = [1,2,3]
>>> sum_result = 0
>>> for x in lst: sum_result += x
...
>>> sum_result
6

  Remember: functions are objects

Remember, in the first part of the study, we kept emphasizing that variables have no type and data has type, and the data we encountered at that time included strings, values, lists, tuples, dictionaries, and files, all of which were treated as objects. Functions, like them, are objects. So you can do the same object-oriented operations as previous objects: assign values, pass them to other functions, embed them in data structures, return them from one function to another, and so on. Of course, there is something special about a function, which is that it can be called by a list of arguments in parentheses following a function expression.


>>> def newsum(lst):        # So let's take this recursive function again
...     print lst
...     if not lst:
...         return 0
...     else:
...         return lst[0] + newsum(lst[1:])
... >>> lst = [1,2,3] >>> newsum(lst)     # This is the method that has been used before
[1, 2, 3]
[2, 3]
[3]
[]
6
>>> recusion_fun = newsum   # Let the variable through the assignment statement recusion_fun Functions are also referenced newsum(lst) object
>>> recusion_fun(lst)       # Thus the variable can implement the operation equivalent to the function call
[1, 2, 3]
[2, 3]
[3]
[]
6

  Let's do another example, and in this case, it's important to remember that functions are objects. Did you ever remember? In the list, you can hold any object, so can you hold a function?

>>> fun_list = [(newsum,[1,2,3]),(newsum,[1,2,3,4,5])]
>>> for fun,arg in fun_list:
...     fun(arg)
...
[1, 2, 3]
[2, 3]
[3]
[]
6
[1, 2, 3, 4, 5]
[2, 3, 4, 5]
[3, 4, 5]
[4, 5]
[5]
[]
15

  A function is really an object.

Since it's an object, you can view the information in dir(object) mode:


>>> dir(newsum)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> dir(newsum.__code__)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
>>> newsum.__code__.__doc__
'code(argcount, nlocals, stacksize, flags, codestring, constants, names,n      varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])nnCreate a code object.  Not for the faint of heart.'
>>> newsum.__code__.co_varnames 
('lst',)
>>> newsum.__code__.co_argcount
1

  So, you guys, when you're using a function, you want to think about it at the level of an object, it's not something special, it's still an object, even though we've spent a lot of time talking about it.


Related articles: