1 variable length parameters and keyword parameters
*args
Represents arbitrary length variable parameters
**kwargs
Represents the keyword parameter
Used *args
and **kwargs
just for convenience and did not enforce their use.
The default parameter is when the function is called, and if the value of the default parameter is not passed in, the value is passed in to the defaults preset .
Note: All parameters with default values must be placed at the end of the parameter list.
def=18=True )print_info("zhan"=False )def*nums ,**nums )
You can use it when you're not sure how many parameters you're going to pass in your function *args
. For example, it can pass any number of arguments:
>>>def print_everything(*args): forinenumerate(args):... print‘{0}. {1}‘.format(count, thing)...>>> print_everything(‘apple‘‘banana‘‘cabbage‘)0. apple1. banana2. cabbage
Similarly, **kwargs
allows you to use parameter names that are not defined in advance:
>>>def table_things(**kwargs):... forin kwargs.items():... print‘{0} = {1}‘.format(name, value)...>>>=‘fruit‘=‘vegetable‘== fruit
*args
And can be in the definition of a function at the **kwargs
same time, but *args
must be in **kwargs
front.
You can also use and syntax when calling *
functions **
. For example:
>>>def myPrint(a, b, c):... print‘a = {0}, b = {1}, c = {2}‘.format(a,b,c)...>>>= [‘aardvark‘‘baboon‘‘cat‘]>>> myPrint(*=== cat
As you can see, it passes each item of the list (or tuple) and unpack it. Note that they must match the arguments in the function. Of course, you can also use * in the function definition or function call.
2 facets-oriented AOP and adorners
AOP is actually the aspect-oriented programming, the Python implementation method uses the adorner pattern.
? adorners are a well-known design pattern that is often used for scenes with cut-off requirements, with more classic insert logs, performance tests, transaction processing, and more. Decorators are a great design for solving such problems, and with adorners, we can pull out a lot of the same code that is not relevant to the function itself and continue to reuse it. In summary, the role of the adorner is to add additional functionality to an already existing object.
def makebold (FN): def wrapped (): return "<b>" + fn () + return wrappeddef makeitalic (FN): def wrapped (): return "<i>" + fn () + return wrapped @makebold @makeitalic def hello (): return Span class= "st" > "Hello World" print hello () ## returns <b><i >hello world</i></b>
Understanding the adorner first understands that the Python function is also an object, since the object can be used as the return value of a function, you can perform replication, add attributes, and pass as function arguments, which is the basis for implementing adorners.
defBread (func):defWrapper ():Print "</" "\>"Func ()Print "<\______/>" returnWrapperdefIngredients (func):defWrapper ():Print "#tomatoes #"Func ()Print "~salad~" returnWrapperdefSandwich (Food="--ham--"):PrintFoodsandwich ()#outputs:--ham--Sandwich=Bread (Ingredients (sandwich))#装饰器实际就是函数调用Sandwich ()#输出:#</ "' \># #tomatoes ##--ham--# ~salad~#<\______/>
As programmers must learn to be lazy, Python uses @ as the adorner syntax sugar and learns some advanced uses:
@bread@ingredientsdef sandwich(food="--ham--"): print foodsandwich()#输出: 是不是觉得简单很多啦!#</‘‘‘‘‘‘\># #tomatoes## --ham--# ~salad~#<\______/>#改变顺序会有影响的,执行顺序是先里面@ingredients,在执行@bread
The parameter of the adorner
def a_decorator_passing_ Arguments (function_to_decorate): def a_wrapper_accepting_arguments (arg1, arg2): print , Arg1, arg2 function_to_decorate (arg1, arg2) return A_wrapper_accepting_ar Guments# when you invoke the function returned by the adorner, the wrapper is called, the parameters are passed into the wrapper, and # it will pass the parameters to the decorated function. @a_decorator_passing_arguments def print_full_name (first_name, last_name): print "My name is" , first_name, Last_nameprint_full_name ( "Peter" , "Venkman" ) # output: #I got args! Look:peter Venkman #My name is Peter venkman
Decorative Decoration method
defMethod_friendly_decorator (method_to_decorate):defWrapper Self, lie): Lie=Lie- 3 # Women's Gospel:-) returnMethod_to_decorate ( Self, lie)returnWrapperclassLucy (Object):def __init__( Self): Self. Age= + @method_friendly_decorator#装饰类方法 defSayyourage ( Self, lie):Print "I am%s, what do you think? " %( Self. Age+Lie) l=Lucy () L.sayyourage (-3)#输出: I am, What do you think?
Adorner self-transmitting parameters
defDecorator_maker_with_arguments (DECORATOR_ARG1, DECORATOR_ARG2):Print("I make decorators! and I Accept arguments: ", DECORATOR_ARG1, DECORATOR_ARG2)defMy_decorator (func):Print("I am the Decorator", DECORATOR_ARG1, DECORATOR_ARG2)# Don't forget the adorner parameters and function parameters! defWrapped (FUNCTION_ARG1, FUNCTION_ARG2):Print("\ t-From the decorator:{0} {1}\ n" "\t-from the function call: {2} {3}\n" "then I can pass them to the decorated function".format(Decorator_arg1, Decorator_arg2, Function_arg1, FUNCTION_ARG2))returnFunc (FUNCTION_ARG1, FUNCTION_ARG2)returnWrappedreturnMy_decorator@decorator_maker_with_arguments("Leonard","Sheldon")defDecorated_function_with_arguments (FUNCTION_ARG1, FUNCTION_ARG2):Print("I am the decorated function and only knows about my arguments:{0}" ' {1} '.format(FUNCTION_ARG1, FUNCTION_ARG2)) Decorated_function_with_arguments ("Rajesh","Howard")#调用函数#输出:#I make decorators! and I accept Arguments:leonard Sheldon#I am the decorator. Leonard Sheldon#-from the Decorator:leonard Sheldon#-from the function Call:rajesh Howard#Then I can pass them to the decorated function#I am the decorated function and only knows about my Arguments:rajesh Howard
3 Duck Type
"When you see a bird walking like a duck, swimming like a duck and barking like a duck, the bird can be called a duck." ”
We do not care about what type of object it is, whether it is a duck or just behavior.
In Python, for example, there are a lot of file-like things, such as Stringio,gzipfile,socket. They have many of the same methods, and we use them as files. Another example of the List.extend () method, we do not care whether its parameter is a list, as long as it is iterative, so its parameters can be list/tuple/dict/string/generator and so on.
Duck types are often used in dynamic languages and are very flexible, so Python doesn't specialize in a lot of design patterns like java.
classDuck ():defWalk Self):Print(' I Walk Like a duck ')defSwim Self):Print(' I swim like a duck ')classPerson ():defWalk Self):Print(' This one walk like a duck ')defSwim Self):Print(' This mans swim like a duck ')defWatch_duck (animal):#定义一个函数, accept animal parameters, need to have walk swim two skillsAnimal.walk () Animal.swim () Small_duck=Duck ()#实例化鸭子Watch_duck (Small_duck)#能调用就认为是鸭子类型Output>>I Walk Like a ducki swim like a duck duck_like_man=Person ()#实例化人, but people also have walk swim methodsWatch_duck (Duck_like_man)#同样被认为是鸭子类型Output>>This one walk like a duckthis man swim like a duckclassLame_foot_duck ():defSwim Self):Print(' I am lame but I can swim ') Lame_duck=Lame_foot_duck ()#实例化蹩脚的鸭子, there are only swim methods under the classWatch_duck (Lame_duck)#虽然是鸭子, but not considered a duck typeOutput>>Attributeerror: lame_foot_duck instance has no attribute' Walk '
4 Overloading in Python
function overloading is mainly to solve two problems.
- Variable parameter types
- Number of variable parameters
The characteristics of an object are not determined by its type, but by the methods in the object, so function overloading is meaningless in dynamic languages.
In addition, a basic design principle is that only if the function of the two functions is identical except for the parameter types and the number of parameters, then the function overloading is used, and if the functions of two functions are different, then the overloads should not be used, instead a function with the same name should be used.
So for scenario 1, the function is the same, but the parameter types are different, how does python handle it? The answer is that there is no need to deal with it, because Python can accept any type of argument, and if the function is the same, then the different parameter types are probably the same code in Python, and there is no need to make two different functions.
So for scenario 2, the function is the same, but the number of parameters is different, how does python handle it? As you know, the answer is the default parameter. Setting the default parameters for those missing parameters solves the problem. Because you assume that functions function the same, then those missing parameters are needed.
Well, given that scenario 1 and Scenario 2 have a solution, Python naturally does not need function overloading
class Write: @staticmethod def write(output,content): #output对象只要实现write方法,不管接受的类型 output.write(content)#stringIO类型= StringIO.StringIO()Write.write(output,‘helloworld‘)#file类型=open(‘out.txt‘,‘w‘)Write.write(output,‘helloworld‘)
Python adorner AOP variable length parameter duck type overload (iii)