[ TOC]
The most important method for FILE files in Python is the open() method Z, which is used to open a file and return the file object. This function is required to process the file;
open(file, mode='rt') #The default is text mode read-only open,If you want to open in binary mode,Add b.
open(file, mode='rt',[buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None]) #Complete grammar
# Parameter Description:
file:Required,File path (relative or absolute path).
mode:Optional,File open mode
buffering:Set buffer
encoding:Generally use utf8
errors:Error level
newline:Distinguish newlines
closefd:Incoming file parameter type
# If the file cannot be opened,Will throw OSError
# The method of the File object refers to the Python3 built-in functions in the notes
Use Python to open files and read content, write content, you need to pay attention to writing Chinese characters* (choose utf-8 encoding)*
#! /usr/bin/python3
# coding:utf-8
# Principle: File system
# /****Case 1: File content traversal***/
file =open('python.txt','r+',encoding='utf-8')
# It is not recommended to use the following methods to output the contents of the file;
# file.seek(0,0)
# lines =list(file)
# for eachline in lines:
# print(eachline,end="")
# The alternative method directly adopts the file object method (recommended)
print("The file descriptor is: %d"%file.fileno())print("Whether to connect to a terminal device",file.isatty())
file.seek(0,0)for eachline in file:print(eachline,end="")
file.close()
# /****Case 2:File content split***/
def save_file(boy,girl,count):
file_name_boy ='boy_'+str(count)+'.txt'
file_name_girl ='girl_'+str(count)+'.txt'
afile =open(file_name_boy,'w',encoding='utf-8') #Pay attention to writing coding
bfile =open(file_name_girl,'w',encoding='utf-8')
afile.writelines(girl)
bfile.writelines(boy)
afile.close()
bfile.close()
def split_file(filename):
f =open(filename,'r',encoding='utf-8') #Pay attention to reading coding
Aauthor =[]
Bauthor =[]
count =1for lines in f:if lines[:6]!='======':(role,spoken)= lines.split(':')if role =='A':
Aauthor.append(spoken) #List add
elif role =='B':
Bauthor.append(spoken)else:save_file(Bauthor,Aauthor,count)
# Re-A/Set B to empty list
Aauthor =[]
Bauthor =[]
count +=1
# A file retention is required after the loop ends,Because only twice'======',Beginners are easy to make mistakes
save_file(Bauthor,Aauthor,count) #key point
f.close()split_file('demo2-10.txt')
########################### Test Results########################################
# C:\Users\Administrator\Desktop\Python\2>python demo2-10.py
# The file descriptor is:3
# Whether to connect to a terminal device False
# #1 :test
# #2: nAME = wEIYIgeek
# #3 :password =123456
Description: Store various python data types in the disk in binary form, which is equivalent to database deserialization, and you need to import the pickle package for reading and reading operations;
The essence of pickle is to use some algorithms to "pick" your data objects into binary files and store them on the disk. Of course, they can also be placed in a database or transferred to another computer via the network.
#! /usr/bin/python3
# Function: Data serialization(Binary)import pickle
import os
value = dict.fromkeys((1,2,3,5,6),'pickle')print(value)
def pkldown(filename):if os.path.exists(filename):print("File already exists and is opening",end="")
f =open(filename,'wb')else:
f =open(filename,'wb')
pickle.dump(value,f)
f.close()
def pklget(filename):
f =open(filename,'rb')
getv = pickle.load(f) #Note to use first'rb'Open file
f.close()print(" %s "%getv)pkldown('test.pkl')pklget('test.pkl')
WeiyiGeek.open function mode attribute parameter
Note: Use pickle to save as a "*.txt" type file, but save as a binary file, and open it directly is garbled;
Summarize the importance of the exception handling mechanism:
Due to the uncertainty of the environment and the unpredictability of user operations, various problems may occur in the program. Therefore, the most important exception mechanism is to enhance the robustness of the program and the user experience, and capture all predicted exceptions as much as possible. Write the handling code, when an exception occurs, the program will automatically digest and return to normal (not to crash);
**Try statement syntax: **
try:
Detected code block
execpt Exception [as reaon]:
Code executed after an exception
else:
When no abnormality occurs,The statement in the else will be executed
**try-finally statement: **
try:
Detected code block
execpt Exception [as reaon]:
Code executed after an exception
else:
When no abnormality occurs,The statement in the else will be executed
finally:
Code that will be executed no matter what
# The raise statement throws an exception
raise system exception name('wrong description')
# with statement follow file I/O automatic release(No need to manually release),When the statement processes multiple items,Can be written as a sentence separated by commas)e
withopen('data.txt','w')as file object:
# Case
withA()as a,B()as b:
suite
**Error and exception throwing case: **
#! /usr/bin/python3
# Program exception handling
# Case 1: No matter what kind of error, our processing code will be executed
try:
sum =1+'a'
except:print("The program has an error BUG, [This method is not recommended in practice]")
# Installation 2: The specified exception performs the specified operation
try:
f =open('noexsitfile.txt') #Run here and jump directly to the OSerror exception execution response code
print("----------------------")
f.write("I exist")
sum =1+'b'
except OSError as err:print("OSError:",str(err))
except TypeError as err:print("TypeError:",str(err))print("----------------------")
# Case 3: Specify different exceptions to execute the same exception handling code,In the end, it will execute if no exception is thrown
try:
f =open('noexsitfile.txt','w',encoding='utf-8') #Run here and jump directly to the OSerror exception execution response code
print(f.write("I exist"))
sum =1+'b'except(OSError,TypeError)as identifier:print("The program is abnormal:",str(identifier))finally:print("Close the open file regardless of throwing an exception")
f.close()print("-------------------------")
# Case 4: Throw the specified exception
try:if'a'>'b':
raise TypeError("We are abnormal")else:
raise NameError("I will be abnormal") #Throw the specified exception
except(TypeError,NameError)as errvalue:print("Custom exception reason:",errvalue)print("-------------------------")
# Case 5: try....except...else...finally statement,When no abnormality occurs,The statement in the else will be executed
try:print(1/2)
except TypeError as identifier:print("wrong reason:",str(identifier))else:print("I will execute without exception")finally:print("I have to execute no matter what is wrong")print("----------------------")
# Case 6 with the use of language
try:withopen('with.txt','w',encoding='utf-8')as f:
f.write("Test ... Test")print("Complete file writing")
except OSError as reson:print("Something went wrong",str(reson))else:print("Nothing wrong,Open files will be closed automatically")
WeiyiGeek. Error and exception throwing case
def file_compare(file1, file2):withopen(file1)as f1,open(file2)as f2: #worth learning
count =0 #Statistics rows
differ =[] #Count the number of different
for line1 in f1:
line2 = f2.readline()
count +=1 #File function comparison
if line1 != line2:
differ.append(count)return differ
file1 =input('Please enter the first file name to be compared:')
file2 =input('Please enter another file name to be compared:')
differ =file_compare(file1, file2)iflen(differ)==0:print('The two files are exactly the same!')else:print('Two files are shared [%d] Different:'%len(differ))for each in differ:print('First%d is not the same'% each)
OOP thought:
Several features of object-oriented:
WeiyiGeek. Class/Class Object and Instance Object
Class attributes and methods
classTest:
count =0 #Static properties
public_attrs =0 #Public property
__ private_attrs =0 #private
def __init__(self):
C.count = C.count +1 #Class name.Attribute name form reference (every instantiation+1)
def prt(self):print('This is public method') #Public method
print(self)print(self.__class__)
self.__foo() #Call private method
def __foo(self): #Private method
print('This is a private method')
def getCount(self):return C.count #Application of static properties of the class (count the number of times the class is instantiated)
t =Test()
t.prt()
# note#
t._Test__private_attrs #Call private properties directly from outside
t._Test__foo() #Call private methods directly from outside
############### The execution result of the above example is:#############################
# This is public method
# <__ main__.Test instance at 0x100771878> #self represents an instance of the class,Represents the address of the current object
# __ main__.Test #self.class points to the class
# This is a private method
# This is a private method#Private method called externally
Object packaging case:
#! /usr/bin/python3
# Instantiate objects and types
# Case 1: Package characteristics
classPerson:
name ='WeiyiGeek' #Attributes
age =20
msg ='I Love Python'
# Define private attributes,Private properties cannot be accessed directly outside the class
__ weight =120
def printname(self): #method
print(self.name,self.age,self.msg,self.__weight)
people =Person() #Instantiate
people.printname() #Object.method
# Python actually uses a technology called "name mangling",The variable name that starts with a double underscore has been cleverly changed.,We can still pass the "_Class name__Variable name" access:
print("body weight:",people._Person__weight,'KG')
# Case 2: Package characteristics
classRectangle:
length =5
width =6
# Set length and width
def setRect(self,length,width):
self.length = length
self.width = width
# Get length and width
def getRect(self):print("The length and width of the rectangle are:%d , %d"%(self.length,self.width))
# Get area
def getArea(self):print("Rectangular area=",self.width * self.length)
# Get the circumference
def getGirth(self):print("Rectangular circumference=",2*(self.width + self.length))
rect =Rectangle()
rect.setRect(15,16)
rect.getRect()
rect.getArea()
rect.getGirth()
############ Results of the##############
# WeiyiGeek 20 I Love Python 120
# body weight:120 KG
# The length and width of the rectangle is: 15,16
# Rectangular area=240
# Rectangular circumference=62
Inherited search:
WeiyiGeek. Inherited search
Inheritance syntax:
class subclass name(Base class,father,Or superclass name)
Case:
#! /usr/bin/python3
# Instantiate objects and types
# Case 1: Single inheritance example
# father
classPerson:
name ='' #Define basic attributes
__ UID =0 #Private property
# Magic method
def __init__(self,*args):
self.name = args[0]
self.__UID = args[1]
# Class method
def speak(self):print("%The ID number of s is%d"%(self.name,self.__UID))
# Subclass
classStudent(Person):
grade =''
def __init__(self,*args):
# Call the constructor of the parent class
Person.__init__(self,args[0],args[1])
self.grade = args[2]
# Override the speak method of the parent class
def speak(self):print("Name:%s ,grade:%s ,identity number%d Since it is a private variable of the parent class, self cannot be called like this._Person__UID "%(self.name,self.grade,Person._Person__UID))
xs =Student('WeiyiGEEK',512301031998010937,'Class of 2018')
xs.speak()
## Case 2: Multiple inheritance
# The following code,Class A,B represents different functional units,C is A,Combination of B functions,这样类C就拥有了Class A,B's function.
classA:
def get_a(self):
print 'a'classB:
def get_b(self):
print 'b'classC(A, B): #Class C is Class A/Subclasses of Class B
pass
c =C()
c.get_a()
c.get_b()
## Case 3: The base class of dynamic inheritance is dynamic (sometimes A, sometimes B)
## Implementation: First define an alias for the base class. When defining the class, use the alias to replace the base class you want to inherit
BaseAlias = BaseClass #Alias the base class
classDerived(BaseAlias): #Note that this parameter is an alias of the base class
def meth(self):
BaseAlias.meth(self) #Access base class through alias
...
############################## Results of the################################
# Name: WeiyiGEEK,Grade: 2018,ID number 0 cannot be called like this because it is a private variable of the parent class: self._Person__UID
# a
# b
#
( Supplement): Combination introduction*Q: What is combination (composition)? *
Answer: The Python inheritance mechanism is very useful, but it is easy to complicate the code and rely on implicit inheritance. So often, we can use combination instead. Combining in Python is actually very simple, put the required class directly in the class definition to instantiate it.
Simply put, composition is used in the "has one" scene, and inheritance is used in the "is one" scene
#* Class combination (horizontal)*#
# Turtles
classTurtle:
def __init__(self, x):
self.num = x
# Fishes
classFish:
def __init__(self, x):
self.num = x
# Pool class
classPool:
def __init__(self, x, y):
self.turtle =Turtle(x) #Combination turtles come in (key points)
self.fish =Fish(y) #Combination of fish to enter the pass (key point)
def print_num(self):print("There are a total of turtles in the pool%d only,Small fish%d!"%(self.turtle.num, self.fish.num))>>> pool =Pool(1,10)>>> pool.print_num()
(Supplement): super() super class
Python strictly requires methods to have instances before they can be called. This limitation is actually the so-called binding concept of Python;
#! /usr/bin/python3
# Function: Implementation of super super class
import random as r #Alias
classFish:
def __init__(self):
self.x = r.randint(0,10)
self.y = r.randint(0,10)
def move(self):
self.x -=1print("My position is:",self.x,self.y)classShark(Fish):
def __init__(self):super().__init__() #Method 1: Only need to set super()Refers to the parent class
# Fish.__init__(self) #Method 2:Call the parent class constructor
self.hungry = True
def eat(self):if self.hungry:print("hungry,Want to eat@!")
self.hungry = False
else:print("Too supportive,Can't eat")
demo1 =Shark()
demo1.move()
demo1.eat()
demo1.eat()
demo1.move()
######### Results of the########
# My position is: 05
# hungry,Want to eat@!
# Too supportive,Can't eat
# My position is:-15
Magic methods are embodied and they can always be called automatically at an appropriate time;
(0) new(cls[,...]) #The first to perform the magic method, usually returns the instantiated object of the class, when you inherit the immutable type but need to modify it;
(1) init(self[,…])
(2) del(self) #Garbage collection mechanism, similar to the destructor method in C++
(3) add(self,other) #Magic method calculation-others are similar
(4) and(self,other) #Magic method logical operator
(5) radd(self,other) #Magic method reverse operation such as a + b, if the a object does not support the + operation, then use the processing scheme of b to add;
(6) rsub(self,other) #The magic method is the same as above
(7) str(self) #If the string needs to be output, print output must be used
(8) repr(self) #String is output directly without external function
(9) getattr(self,name) #The magic method of attribute access, which defines when the user tries to get a non-existent attribute;
(10) getattribute(self,name) #Define the behavior when the attributes of this class are accessed
(11) setattr(self,name,value) #Define the behavior when an attribute is set
(12) delattr(self,name) #Define the behavior when an attribute is deleted
(13) get(self,instance,owner) #descriptor, used to access the attribute, it returns the value of the attribute
(14) set(self,instance,value) #will be called in the attribute assignment operation and will not return anything
(15) delete(self,instance) #Control the delete operation and return any content
(16) len() #The container is triggering triumphantly in the len(object) method
(17) getitem() #triggered when the container key value is obtained, such as dictionary dict['key']
(18) setitem() #Set the behavior of the specified element in the container, such as dictionary dict['key'] = 1024
Case 1: Define an amusement park ticket class according to the following requirements, and try to calculate the weekday ticket price for 2 adults + 1 child. The difficulty of object-oriented programming lies in the transformation of thinking.
# Weekday ticket price 100 yuan
# Weekend fare is 120 on weekdays%
# Half ticket for children
# Case 1:
classTicket():
def __init__(self, weekend=False, child=False):
self.exp =100if weekend: #According to sunday/Children to calculate
self.inc =1.2else:
self.inc =1if child: #Child's price
self.discount =0.5else:
self.discount =1
def calcPrice(self, num):return self.exp * self.inc * self.discount * num #Key point here
adult =Ticket()
child =Ticket(child=True)print("2 adults+The weekday fare for 1 child is:%.2f"%(adult.calcPrice(2)+ child.calcPrice(1)))
# Case 2:
# When instantiating an object,This variable+1,When destroying an object,This variable自动-1)
classCount:
count =0
def __init__(self): #Instance initialization
Count.count +=1
def __del__(self): #del call triggers the magic method
Count.count -=1
def getCount(self):print("The current count%d value"%Count.count)
a =Count() #Trigger init
b =Count()
c =Count()
d = a #Here is the reference of d to a
e = a
print(Count.count)
del d #Note: del will not be triggered here(Del can only be triggered after all references are deleted)
del e #Can't trigger here either
del a #Trigger del
print(Count.count)
# Case 3:
# CapStr inherits an immutable class
classCapStr(str):
def __new__(cls,string):
string = string.upper() #Turn immutable types into sizes
return str.__new__(cls,string) #Return the modified character to the object
a =CapStr('I love Study Python3!')print(a)
############### Results of the#################
# 2 Adults+Weekday fare for 1 child: 250.00
# 3
# 2
# I LOVE STUDY PYTHON3!
(2) Class algorithm calculation magic method
Description: Before Py2.2, classes and types were separated (actually the encapsulation of classes and attributes), but afterwards the author unified (converted Python types into factory functions), for example:
Factory functions are actually a class object. When you call them, you actually create a corresponding instance object.
# The actual engineering function is the class object
>>> type(len)<class'builtin_function_or_method'> #Built-in function
>>> type(int) #Types are all class objects
< class'type'>>>>type(tuple)<class'type'>>>>classC:... pass
...>>> type(C) #Class definition
< class'type'>
# Py2.2 before
# int('123') #It actually calls int and returns an integer value
# py2.After 2
a =int('123') #Is actually an instantiated object
Case 2:
#! /usr/bin/python
# Class magic algorithm operation case
# Inherit the int class
classNewint(int):
def __add__(self, value):returnsuper().__add__(value) #super is the super class refers to the parent class
def __sub__(self, value):
# returnsuper().__sub__(value) #Method 1 returnint(self)-int(value) #Method 2,Note that type conversion must be forced here,If you go to the following, it will report an error recursive loop exception
# return self - value #RecursionError: maximum recursion depth exceeded in comparison
def __and__(self, value): #The magic method=&returnsuper().__and__(value)
a =Newint(8)
b =Newint(6)print("a + b =",a + b)print("a - b =",a - b)print("a & b =",a & b)
# Case 3: Python magic method operation is similar to C++Operator overloading
classint(int):
def __add__(self,other):return int.__sub__(self,other) #Overload key points
a =int('5')
b =int('4')print("Operator overloading: a+ b => a - b =", a + b)
######## Execution effect###########
# a + b =14
# a - b =2
# a & b =0
# Operator overloading: a+ b => a - b =1
(3) Class inverse algorithm calculation magic method
Case:
#! /usr/bin/python
# Case 1: Inverse operator
classNewint(int):
def __radd__(self, value): #Inverse operation+return int.__sub__(value,self) #Method 1: The execution is subtraction, the order of value self will affect who is subtracted/Minute
def __rsub__(self, value): #Inverse operation
returnsuper().__add__(value) #Method 2: Perform subtraction
def __rmul__(self, value):returnsuper().__truediv__(value)
a =Newint(5)
b =Newint(3)print(a + b) #Since object a can support+/-,So it will not trigger the inverse operation
print(a - b)
# Since 1 is a non-object, use the method of b
print("1 + b =",1+ b) # 1-3=>-2 Due to the changed value,self order
print("1 - b =",1- b) #Trigger inverse operation=>3+1=4print("1 * b =",5* b) #Trigger inverse operation=>3/5=0.6
# Case 2: Unary operator
classOneInt(int):
def __pos__(self): #Define negative sign behavior-x
returnsuper().__pos__() # -(self)
a =OneInt(-1)print("-(a) =",-a) #Unary operator is triggered at this time-(-1)
######### Results of the########
# 8
# 2
# 1+ b =-2
# 1- b =4
# 1* b =0.6
# - ( a)=1
(4) The supplementary magic method of the class
#! /usr/bin/python
classDemo:
def __str__(self):return'I'm__str__Magic method,Need print()Output'classDemo1:
def __repr__(self):return'2 -I'm__repr__Magic method,Direct object output'
a =Demo()print("1 -",a)
b =Demo1()print(b) #in>>>b can be output directly
################ Results of the#################
# 1- I'm__str__Magic method,Need print()Output
# 2- I'm__repr__Magic method,Direct object output
(5) Class attribute access magic method
Set and call methods through class attributes;
#! /usr/bin/python
# Magic method of property access
# Method case 1:
classAttrView:
def __getattribute__(self, name):print("Call the getattribute magic method")returnsuper().__getattribute__(name) #super()Obtain the base class automatically, this class has no inherited class, the default is the object class
def __getattr__(self,name):print('Call the getattr magic method')
def __setattr__(self,name,value):print("Call the setattr magic method")super().__setattr__(name,value)
def __delattr__(self, name):print('Call the delattr magic method')super().__delattr__(name)
demo =AttrView()
demo.x #Trigger to call getattribute when there is no attribute/getattr(No trigger)Magic method
setattr(demo,'x',1) #Set attributes call setattr magic method
demo.y =1 #Set attributes call setattr magic method
demo.y #Get attributes call getattribute magic method
delattr(demo,'y') #Delete attributes call delattr magic method
# Method case 2:
classRectangle:
def __init__(self, width =0, height =0):
self.width = width #Will trigger__setattr__Magic method
self.height = height
def __setattr__(self, name, value):if name =='square': #square
self.height = value
self.width = value
else:super.__setattr__(self, name, value) #Method 1: Prevent infinite recursion errors(It is recommended to use the setattr method of the base class)
# self.__dict__[name]= value #Method 2
def getArea(self):return self.width * self.height
def getPeri(self):return(2*(self.width)+2*(self.height))
r1 =Rectangle(4,5)print("Rectangular area:",r1.getArea())
r1.square =10 #Create an attribute to indicate that it is square
print("Square area: ",r1.getArea())print("Square perimeter:",r1.getPeri())print("__dict__",r1.__dict__) #Put all the attributes of the class back to the dictionary type
########## Results of the####################
# Rectangular area: 20
# Square area:100
# Square perimeter: 40
# __ dict__ {'width':10,'height':10}
(6) Magic method of custom sequence
Description: Protocols are very similar to the interfaces in other programming languages. It stipulates that those methods must be defined; however, the protocol in Python is not so formal; in fact, the update is a guide;
Requirement: write an unchangeable custom list, and record the number of times each element is accessed;
#! /usr/bin/python3
# Function: Container sequence custom type agreement()
# - *- coding:utf-8-*-classCountnum:
def __init__(self,*args):
self.value =[x for x in args] #List expression
self.count ={}.fromkeys(range(len(self.value)),0)
def __len__(self):returnlen(self.value)
def __getitem__(self,index):
self.count[index]+=1return self.value[index]
a =Countnum(1,3,5,7,9)
b =Countnum(2,4,6,8,10)print(a[1],b[1])print(a[1],b[1])print("The sum of two object sequences:",a[3]+b[3])print("Number of visits of A:",a.count)print("Number of visits to object B:",b.count)
############ Results of the################
# $ python demo3.23.py
# 34
# 34
# The sum of the sequence of two objects: 15
# Number of visits of A:{0:0,1:2,2:0,3:1,4:0}
# Number of visits to object B:{0:0,1:2,2:0,3:1,4:0}
Description: Descriptor is to assign an instance of a particular type of class to the property of another class; for example, property() is a weird BIF, which serves to access methods as properties, thereby providing a more friendly access method ;
A descriptor is a class, a class that implements at least any of the three special methods get(), set() or delete()
#! /usr/bin/python
# Class attribute-Descriptor
# Define a class,In order to realize the original property principle, the following three magic methods must be used
# Case 1classDecriptor:
def __get__(self,instance,owner):print("getting ... ",self, instance, owner) #The parameters represent(Decriptor itself,Class object test,Test class itself)
def __set__(self,instance,value):print("setting ... ",self, instance, value)
def __delete__(self,instance):print("deleting ...",self,instance)classTest:
x =Decriptor() #Decriptor()Instance of class/Descriptor called attribute x
test =Test()
test.x
test.x ='ceshi'
del test.x
############ Results of the#######
# getting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940><class'__main__.Test'>
# setting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940> ceshi
# deleting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940>
# Case 2: Custom property
classMyProperty:
def __init__(self, fget=None, fset=None,fdel=None): #Three methods of other classes
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self,instance,owner):return self.fget(instance) #Method of passing in instance object
def __set__(self,instance,value):
self.fset(instance,value)
def __delete__(self,instance):
self.fdel(instance)classC:
def __init__(self):
self._x = None
def getX(self):return self._x
def setX(self, value):
self._x = value
def delX(self):print("delete destroy attribute!")
del self._x
# Descriptor of the x object (pass into the three methods in the class)
x =MyProperty(getX,setX,delX) #Class instance
c =C()
c.x ='Property'print(c.x,c._x)
del c.x
######################
# Property Property
# delete destroy attribute!
Modifiers are a well-known design pattern, which is often used in scenarios with aspect requirements. The more classic ones include inserting logs, performance testing, transaction processing, etc.; with modifiers, we can extract a large number of functions and function functions. Identical code irrelevant to itself and continue to be reused.
In fact, a modifier is an elegant package, but it should be noted that functions can only be modified within a module or class definition, and a class is not allowed; a modifier is a function, which takes the modified function as a parameter , And return the modified function of the same name or other callable things.
1 ) Introduction and use of @ modifier
In Python functions, you will occasionally see that the previous line of the function definition is decorated with @functionName. When the interpreter reads a modifier like @, it will first parse the content after @, and directly put the function in the next line of @ or Class as the parameter of the function behind @, and then assign the return value to the function object decorated in the next line.
Use Cases:
#! /usr/bin/python
import time
##############################
classDemo(object):
def __init__(self,foo):
self.foo = foo
self.foo() #Call the passed f function
@ Demo #F()The function is passed into the class as a parameter
def f():print("I love Python.org!")
# Case 1:funcA(funcB(func(4)))
def funcA(A): #Note the formal parameters
print("function A")
def funcB(B):print(B(2)) #B(2)Actually passed into func in func(2)s will agree to c**Value of 2
print("function B")
@ funcA
@ funcB
def func(c):print("function C")return c**2
######### Results of the.START########
# I love Python.org!
# function C
# 4
# function B
# function A
######### Results of the.END########
# Case 2: Function
def timeslong(func): #The func parameter,Is under the modifier
def call():
start = time.perf_counter()print("It's time starting ! ")func() #Actually called the f function (func()Is the same as the keyword)
print("It's time ending ! ")
end = time.perf_counter()return"It's used : %s ."%(end - start) #Output printing
return call
# by@timeslong modifies it to achieve the purpose, the whole code is beautiful, and a small part of the code
@ timeslong #Execute timelong first, then call to execute func=>f()
def func():
y =0for i inrange(5):
y = y + i +1print(y)return y
print(func())
######### Results of the.START########
# It's time starting !
# 1
# 3
# 6
# 10
# 15
# It's time ending !
# It's used :0.006445216000000031.
######### Results of the.END########
# Case 3.Modifiers can also be used through classes
classtimeslong1(object):
def __init__(self,func):
self.f = func #The actual incoming is f()function
def __call__(self):
start = time.perf_counter()print("It's time starting ! ")
self.f()print("It's time ending ! ")
end = time.perf_counter()print("It's used : %s ."%(end - start))
@ timeslong1 #Take the following functions or classes as their parameters
def f():
y =0for i inrange(3):
y = y + i +1print(y)return y
f() #Triggered when called@Modifier
######### Results of the.START########
# It's time starting !
# 1
# 3
# 6
# It's time ending !
# It's used :0.00160638099999999.
######### Results of the.END########
2) Built-in modifiers
There are three built-in modifiers, which are used to turn the instance methods defined in the class into static methods (staticmethod ), class methods (classmethod) and class properties (property); note that static methods and class methods are not too useful .
#! /usr/bin/python3
# Function: implement class method/Static method/Class attribute
classHello(object):
def __init__(self):
pass
# Way 1.Class method
@ classmethod
def print_hello(cls):print("Method 1: Call the class method print_hello()",)
# Method 2: It is precisely because the setting of static methods and class methods is too irritating, so the author of Python has developed a form of replacement of function modifiers.
def foo(cls):print("Method 2: Call the class method foo()")
# Will foo()Method is set to class method
foo =classmethod(foo)
# Method 3: Static method (note the giant hole self here)
@ staticmethod
def static_hello(arg):return"Method 4: Call the static method static_hello Value ="+str(arg)
# Comparison of static methods
Hello.print_hello() #After the class method is modified, print_hello()It becomes a class method, you can pass Hello directly.print_hello()Call it without binding the instance object.
Hello.foo()print(Hello.static_hello(1),Hello.static_hello) #Pay attention to the parameters here
######### Results of the################
# Method 1: Call the class method print_hello()
# Method 2: Call the class method foo()
# Method 3: Call the static method static_hello Value =1<function Hello.static_hello at 0x000001F2DB73C950>
# >>> c1 =Hello()
# >>> c2 =Hello()
# # Static method only generates one in memory, saving overhead
# >>> c1.static_hello is C.static_hello #True
# >>> c1.nostatic is C.nostatic # False
# >>> c1.static_hello # <function Hello.static_hello at 0x000001F2DB73C950>
# >>> c2.static _hello # <function Hello.static_hello at 0x000001F2DB73C950>
# >>> Hello.static_hello # <function Hello.static_hello at 0x000001F2DB73C950>
# # Ordinary methods have a separate object for each instance, which is expensive
# >>> c1.nostatic # <bound method Hello.nostatic of<__main__.C object at 0x03010590>>
# >>> c2.nostatic # <bound method Hello.nostatic of<__main__.C object at 0x032809D0>>
# >>> Hello.nostatic # <function Hello.nostatic at 0x0328D2B8>
# Case 3: Using attribute modifiers to create descriptors"
classC:
def __init__(self, size=10):
self.size = size
@ property #Keypoint attribute/The bound property is x
def x(self):return self.size
@ x.setter #
def x(self, value):
self.size = value
@ x.deleter
def x(self):
del self.size
demo =C()print("Get the value of the attribute:",demo.x) #Get the value of the attribute: 10
demo.x =1024print("Get the value of the changed property:",demo.x) #Get the value of the changed property: 1024
del demo.x
Recommended Posts