This article is in the learning route of Tianchi 『python Advanced Foundation 』 plate , I have learned some before , Record some mistakes and unfamiliar places here . Supplement only , Not all knowledge points .
All codes of detailed knowledge points can be found in my GitHub Warehouse TianChi-Studying Find .
python in 『 Everything is the object 』, Functions are no exception .
What I learned before C++
or Java
in , You can find that the return value of the function is either empty , Or some data type , But in python
in , The return value can be any object , Include function .
There are many kinds of parameters of functions , There are mainly :
Positional arguments (positional argument): Is the most common x, y etc.
Default parameters (default argument): Given a default value , Users can also pass in arguments to adjust .
def func(x, y=3):
print(x+y)
func(1) # 4
func(1, 666) # 667
Variable parameters (variable argument): There is no limit to the number of input parameters , Automatically save as A tuple type .
*args
It's a variable parameter ,args
It received a tuple
def printinfo(arg1, *args):
print(arg1)
print(args, type(args))
printinfo(10) # Only one parameter , Not belonging to args Of .
# 10
# () <class 'tuple'>
printinfo(70, 60, 50) # except arg1 Location matched , Others are passed to variable parameters
# 70
# (60, 50) <class 'tuple'>
Key parameters (keyword argument): There is no limit on the number and naming of keywords , It is automatically saved as a dictionary after being imported .
**kw
It's a keyword parameter ,kw
It received a dict
def person(name, **kwargs):
print(name)
print(kwargs, type(kwargs))
if 'age' in kwargs:
age = kwargs['age']
print(f'{
name} This year, {
age} year ')
person(' Zhang San ') # Only one parameter , Not belonging to kwargs Of .
# Zhang San
# {} <class 'dict'>
person(' Li Si ', age=18, height=1.80) # except name Location matched , Others are passed into keyword parameters
# Li Si
# {'age': 18, 'height': 1.8} <class 'dict'>
# Li Si this year 18 year
Named key parameters (name keyword argument)
*
, Otherwise, it's a positional parameter , When calling a function with a named keyword parameter Parameter name must be given .def person(name, *, age, height=1.90):
print(f'{
name} This year, {
age} year , height {
height:.2f}m')
person(' Zhang San ', age=18, height=1.80) # Zhang San this year 18 year , height 1.80m
person(' Li Si ', age=18) # Li Si this year 18 year , height 1.90m
person(' Wang Wu ') # TypeError, You need to pass in the given keyword
Parameter combination
stay Python
When you define a function in , Above this 5 All parameters can be used , d But at most 4 Kind of , And pay attention to the order :
stay python In the program , Variables in different positions , There are different scopes .
It should be noted that :
- When a local variable attempts to access a global variable , Be sure to declare in the function
global
.- When local variables and global variables name conflict when , The program will choose local variables first .
Nested Function Is to define the inner function in the outer function .
def outer():
print('outer The function is called here ')
def inner():
print('inner The function is called here ')
inner() # This function can only be used in outer The function is called internally
outer()
# outer The function is called here
# inner The function is called here
Closure Is an important grammatical structure , Structurally, it is similar to embedded functions , The difference is that the return value , The outer function of a closure The return value is a function .
def funX(x):
def funY(y):
print(' Use funY(y)')
return x * y
return funY
i = funX(8)
print(type(i)) # <class 'function'>
print(i(5)) # 40
Notice in the above code , Internal function
FunY
Variables with external non global scope are used inx
.
The same is , Function scopes nested within functions also need special attention , If we need to modify variables in closure , Need to use nonlocal
keyword .
num = 999
def outer():
num = 10
def inner():
nonlocal num # nonlocal Keyword declaration
num = 100
print(f'inner in num = {
num}')
inner()
print(f'outer in num = {
num}')
outer()
# inner in num = 100
# outer in num = 100
print(f' Global num = {
num}')
# Global num = 999
lambda It should be noted that :
return
, The expression itself is the return value .Anonymous functions are mainly suitable for functional programming ( Functions do not affect anything outside the function ) In some higher-order functions of . for example map Mapping and filter Filter , Of course, you can also use it in your own custom functions .
odd = lambda x: x % 2 == 1
templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(templist)) # [1, 3, 5, 7, 9]
m1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(list(m1)) # [1, 4, 9, 16, 25]
Object oriented must understand three characteristics :
issubclass(B, A)
see B
Whether it is A
Subclasses of . Inherit
and Method rewrite
. We all have a home , His name is China
equally . My wife is just mine
equally .class A():
a = 0 # Class properties
def __init__(self, xx):
A.a = xx # Using class properties, you can use ( Class name . Class properties ) call .
There are some ways to manipulate attributes :
hasattr(object, name)
To determine whether the object contains the corresponding Properties or methods .getattr(object, name)
To get Properties or methods .setattr(object, name, value)
To modify the attribute value , Or create new attributes and values .delattr(object, name)
To delete attributes .class A(object):
name = ' Zhang San '
def set(self, a, b):
x = a
a = b
b = x
print(a, b)
a = A()
print(hasattr(a, 'name')) # To determine if there is name attribute True
print(hasattr(a, 'set')) # To determine if there is set Method True
x = getattr(a, 'name') # Get attribute value
print(x) # Zhang San
c = getattr(a, 'set') # Access method
c(a='1', b='2') # 2 1
Private attributes and methods only need to be defined and named with two underscores "__
" that will do .
Compared with public attributes and public methods , Private properties and private methods are more secure . By definition , Encapsulate the properties and methods that need security protection as private , It can prevent external direct calls , And must use Instantiate object methods
or Class method
To call , To improve security .
But in python The private property in is 『 Pseudo private 』, That is, you can use the class name , adopt object._className__attrName
Access private properties , use object._className__func()
Access private methods .
class JustCounter:
__secretCount = 0 # Private variables
publicCount = 0 # Open variables
def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)
counter = JustCounter()
counter.count() # 1
print(counter.publicCount) # 1
# Special methods can still be accessed
print(counter._JustCounter__secretCount) # 1
# Direct access will report an error .
print(counter.__secretCount)
The instance directly uses spot Can Attribute added 了 , You need to pay attention to this .
class B:
def func(self):
print(' call func Method ')
b = B()
print(b.__dict__) # View the properties {}
b.name = ' Zhang San '
b.age = 18
print(b.__dict__) # View the properties {'name': ' Zhang San ', 'age': 18}
b1 = B()
print(b1.__dict__) # View the properties {}
Magic methods are basically special methods surrounded by underscores . Compared to the ordinary method , It can automatically call when appropriate . The first parameter is generally cls
『 Class method 』 perhaps self
『 Example method 』.
__init__(self[, ...])
Constructors , Initialization method called when an instance is created .__new__(cls[, ...])
The first method called when an object is instantiated , Calling __init__
Before initialization , First call __new__
. __new__
The return value of must be an instance of the current class , Otherwise, it will not call __init__
initialization .int, str, tuple
) when , Provide a way to customize the instantiation process of this class .__del__(self)
Destructor , Methods that are called when an object is about to be recycled by the system .__str__(self)
: When you print an object 、 Use %s
Format or use str
Strong conversion of data types , Trigger __str__
.__repr__(self)
yes __str__(self)
The spare tire of , Similar to , However, customization is often more accurate , Mainly used for debugging .Ordinary calculation cannot be carried out in objects , You need to customize the calculation method .
__add__(self, other)
The act of defining addition : +
__sub__(self, other)
Define the act of subtraction : -
__mul__(self, other)
Define the behavior of multiplication : *
__truediv__(self, other)
The act of defining division : /
__floordiv__(self, other)
Define the behavior of integer division : //
__mod__(self, other)
Define the behavior of the modulus algorithm : %
__divmod__(self, other)
Definition should be divmod()
Behavior at call time divmod(a, b)
Combine the results of divisor and remainder operations , Returns a tuple containing quotient and remainder (a // b, a % b)
.__pow__(self, other[, module])
Definition should be power()
Call or **
The act of calculating __lshift__(self, other)
Define the behavior of bitwise left shift : <<
__rshift__(self, other)
Define the behavior of bitwise right shift : >>
__and__(self, other)
Define the behavior of biting and manipulation : &
__xor__(self, other)
Defines the behavior of bitwise exclusive or operations : ^
__or__(self, other)
To define the act of biting or manipulating : |
And the corresponding Inverse operator , Add before r
that will do , for example __rsub__
. Corresponding incremental assignment operator , Add before i
that will do , for example __isub__
.
__getattr__(self, name)
: Defines the behavior when a user tries to get a nonexistent property .__getattribute__(self, name)
: Defines the behavior of the class when its properties are accessed ( Call the method first , See if the property exists , If it does not exist , And then call __getattr__
).__setattr__(self, name, value)
: Defines the behavior when a property is set .__delattr__(self, name)
: Defines the behavior when an attribute is deleted .A descriptor is a property that assigns an instance of a particular type of class to another class .
__get__(self, instance, owner)
: Used to access properties , It returns the value of the property .__set__(self, instance, value)
: It will be called in the attribute assignment operation , Don't return anything .__del__(self, instance)
: Control delete operation , Don't return anything . Iteration is Python
One of the most powerful features , Is a way to access collection elements .
There are two basic ways to iterator : iter()
and next()
:
iter(object)
Function to generate iterators .next(iterator[, default])
Returns the next entry for the iterator . Return the default value when the element is empty , If not, it will trigger StopIteration
abnormal . stay Tuple derivation and next Used in , It's just the following 『 generator 』. Using a class as an iterator requires two magic methods in the class __iter__()
And __next__()
.
__iter__(self)
Define the behavior of elements in the iteration container , Returns a special iterator object , This iterator object implements __next__()
Method and pass StopIteration
The exception marks the completion of the iteration .__next__()
Returns the next iterator object . StopIteration
Exceptions are used to identify the completion of an iteration , To prevent infinite loops , stay __next__()
Method, we can set to trigger after completing the specified number of cycles StopIteration
Exception to end the iteration .class Fibs:
def __init__(self, n=10):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > self.n:
raise StopIteration
return self.a
fibs = Fibs(100)
for each in fibs:
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89
stay Python in , Used yield
The function of the is called the generator (generator).
yield
The function will Pause and save All current operation information , return yield
Value , And next time next()
Method from the current location continue function .def libs(n):
a = 0
b = 1
while True:
a, b = b, a + b
if a > n:
return
yield a
for each in libs(100):
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89
The partial harvest of function is about 『 Named key parameters 』, I really haven't learned this knowledge before . And the problem of variable scope to further deepen our understanding , Closure functions are amazing , It also needs to be understood .
I also learned the basic knowledge of object-oriented , Especially about magic methods here , It's a lot of content , But there are not many commonly used .
The construction of generators and iterators is also known , I feel that Fibonacci can be used anywhere .