current position:Home>Python: Class Introduction

Python: Class Introduction

2022-02-02 14:14:52 Ice sky

Python class

One 、 Class construction & initialization

adopt __init__ Initialization with built-in functions :

class Student:

	def __init__(self, name, age):
		print('Start initialization...')
		self.name = name
		self.age = age
		
alice = Student('Alice', 20)
bob = student('Bob', 20)
# show address
print(id(alice)) # different address
print(id(bob))
# show dictionary of each student
print(alice.__dict__)
# {'name': 'alice', 'age': 20}
print(bob.__dict__)
# {'name': 'bob', 'age': 20}

adopt __dict__ Code optimization for multi field initialization :

class person:
	''' def __init__(self, name, age, hobby, address, email): # intialization # self.name = name # ... # self.email = email '''
	# using __dict__ to init
	def __init__(self, info):
		self.__dict__.update(info)


perinfos = open('person_info.txt', 'r')
persons = []
for p in perinfos:
	info = p.split(', ')
	persons.append(person(info))

print(persons)

Two 、 Class characteristics

  • polymorphic Polymorphism
  • encapsulation Capsulation
  • Inherit Inheritation

2.1 Class inheritance :Inheritation

2.1.1 The definition of inheritance

###########################################################################################################
###########################################################################################################
### ___ ______ ____ ___ _______ _______ ___ ___ 
### | |\ | | | | | \ | | /\ | | / \ |\ | 
### | | \ | |_____| |____ |____/ | | / \ | | | | | \ | 
### | | \ | | | | | \ | | /----\ | | | | | \ | 
### _|_ | \| | | |_____ | \ _|_ | / \ | _|_ \___/ | \| 
###########################################################################################################
###########################################################################################################


# derived_class - Class this class derived from
class class_name(derived_class):
    
    # some variables
    # some override functions such as: __init__, __call__
    # some user defined function 

2.1.2 multiple inheritance

Python Support for multiple inheritance , Subclasses inherit all variables and methods of the parent class . Variable search method :

  • From bottom to top
  • From left to right
class parent1:
    x = 'parent1 x'
    parent_name = 'parent1'
class parent2:
    x = 'parent2 x'
    parent_name = 'parent2'
class child(parent1, parent2):
    myname = 'myname is child'
    
child = child()
print(child.myname)
print(child.parent_name) # output: parent1 which is first in parent list

2.1.3 Search method

  • Depth-first search (DFS, Depth-First-Search)
  • Breadth first search (BFS, Broadth-First-Search)
Python2: The difference between classic and new classes

Classic class :

class A:

	def echo(self):
		print('I am A')

class B(A):
	# do nothing
	pass

class C:

	def echo(self):
		print('I am C')


class D(B,C):
	pass


d = D()
print(d.echo()) # I am A

The new class :

class A(Object):

	def echo(self):
		print('I am A')

class B(A):
	# do nothing
	pass

class C:

	def echo(self):
		print('I am C')


class D(B,C):
	pass


d = D()
print(d.echo()) # I am C
Python3: Unified breadth first search

Breadth search

2.1.4 Variables and methods

By explicitly calling the function with the same name in the parent class , Implement code optimization .

The inheritance of function is related to

First, we define three classes :

  • person: Base class , Contains a say Methods and a way to increase your salary `
  • staff: According to the salary formula of ordinary employees , Override the salary method in the parent class
  • manager: ditto , But the salary calculation method is different

We have defined different salary calculation formulas in each class , And set the corresponding formal parameters :

class person:

	def __init__(self, name, age, salary):
		self.name = name
		self.age = age
		self.salary = salary

	def say(self):
		s = 'My name is %s, my age is %s, and my price is %s' %(self.name, self.age, self.price)

	def raise_salary(self, percentage):
		self.salary = self.salary * (1 + percentage)

class staff(person):

	def __init__(self):
		pass

	def raise_salary(self, percentage, performance):
		self.salary = self.salary * (1 + percentage + performance)

class manager(person):

	def __init__():
		pass

	def raise_salary(self, percentage, performance, shareoutbonus):
		self.salary = self.salary * (1 + percentage + performance + shareoutbonus)

obviously , At this point, when we want to calculate the salary formula , Or when the parameter is modified , We need to modify every function , However, it is realized by explicitly calling the function function of the parent class in the function function of the child class , You can directly modify the methods in the parent function :

# staff
def raise_salary(self, percentage, performance):
	# self.salary = self.salary * (1 + percentage + performance)
	person.raise_salary(percentage = percentage + performance)
# manager
def raise_salary(self, percentage, performance, shareoutbonus):
	# self.salary = self.salary * (1 + percentage + performance + shareoutbonus)
	person.raise_salary(percentage = percentage + performance + shareoutbonus)
The inheritance of constructors is related to

When a new member variable is added to a subclass , And when you want to pass new variables during construction :

##  Inheritance of constructors 

class person:
	def __init__(self, name, age, price):
		self.name = name
		self.age = age
		self.price = price


class manager(person):

	def __init__(self, address):
		self.address = address


m2 = manager('m2', 20, 1000, 'Dongguan') # error 'cause __init__ has been overrrided

At this point, if the initialization function of the subclass only contains the new field parameters , When constructing, the parameters in the initialization function of the parent class are passed , Report errors , because __init The method of is completely overridden in subclasses , also Python The initialization function of the parent class is not implicitly called for redundant parameters , Therefore, you need to completely rewrite the initialization function , Give the corresponding assignment statement for each field :

##  Inheritance of constructors 

class person:
	def __init__(self, name, age, price):
		self.name = name
		self.age = age
		self.price = price


class manager(person):

	def __init__(self, name, age, price, address):
        self.name = name
		self.age = age
		self.price = price
		self.address = address


m2 = manager('m2', 20, 1000, 'Dongguan') # error 'cause __init__ has been overrrided

obviously , At this time, there are many duplicate codes in the initialization functions of subclasses and parent classes .

When there are a large number of duplicate assignment statements in the initialization function of the subclass and the parent class , Code optimization can be achieved by explicitly calling the initialization function of the parent class :

class person:
	def __init__(self, name, age, price):
		self.name = name
		self.age = age
		self.price = price


class manager(person):

	def __init__(self, name, age, price, address):
		self.address = address
		''' self.name = name self.age = age self.price = price '''
		# instead explicitly called person's initialization method
		person.__init__(self, name, age, price)


m2 = manager('m2', 20, 1000, 'Dongguan') # pass

2.1.5 Inherited application scenarios

  • synthesis
  • polymerization
  • Reuse
synthesis

The life cycle of part and whole is consistent , The whole has control over its organizational part , And a component only belongs to a synthetic relationship , It can't be shared

for example :

  • house : Including rooms s, room s Only belong to this house , The house disappeared , The room disappeared , A strong ownership relationship
  • room : Inside the house , The life cycle is less than or equal to the house , The disappearance of the house must be accompanied by the disappearance of the room
class room:
	def create_room(self):
		print("this is a new room")


class house:
	def __init__(self):
		self.room = room()

	def create_house(self):
		self.room.create_room()


h1 = house()
h1.create_house()
polymerization

Indicates a relationship of ownership , The relationship between the whole and the parts

for example :

  • Student : part , The school closed down , But students still exist , Will not disappear because of the disappearance of the whole , That is, the life cycle of a part can exceed that of the whole
  • Flight class : The whole that contains each student part
#  Student , Part of the classroom 
class student:
	pass

#  classroom , Including the whole of students 
class classroom:
	def __init__(self, student):
		self.student = student


s1 = student()
c1 = classroom(s)

Object relationship :

  • IS-A : I am a person (?), Obviously, this is an inheritance relationship
  • HAS-A: People have brains (?), It's obviously a synthetic relationship

Example :
m a n { i n   c o m p a n y : e m p l o y e e a t   h o m e : h u s b a n d f a t h e r a t   s c h o o l : s t u d e n t man\begin{cases} in\ company:employee\\ at\ home:husband&father\\ at\ school:student \end{cases} manin company:employeeat home:husbandat school:studentfather

class person:
	def show(self):
		print('live a happy life')

class staff:
	def show(self):
		print("try to work hard")



class husband(person):

	def show(self):
		print("work and earn money")


class student(person):

	def show(self):
		pritn("good good study day day up")


p = staff()
p.show()
# different person, not able to create a person with different roles
p = husband()
p.show()


class role:
	def show(self):
		pass


class staff(role):
	def show(self):
		print("try to work hard")



class husband(role):

	def show(self):
		print("try best to make family happy")


class student(role):

	def show(self):
		pritn("good good study day day up")

class person:
	def set_role(self, role):
		self.role = role

	def get_role(self):
		self.role.show()


p = person()
p.set_role(staff)
p.get_role() # "try to work hard"

p.set_role(husband)
p.get_role() # "try best to make family happy"

p.set_role(student)
p.get_role() # "good good study day day up"
Reuse

l o a d i n g … loading\dots loading

2.1.6 The Demeter principle : The principle of least knowledge

Ensure encapsulation , Reduce the internal exposure of classes , Example :

  • A class : By B rely on , Expose only the methods and properties that must be provided , That is, define the visible range of methods and attributes
  • B class : Depend on A, Rely only on what should be relied on , That is, only want to provide information to the object that needs to provide information , Don't expose content to unrelated classes

for example :

class A:
	def __init__(self, name):
		self.name = name
	def get_b(self, name):
		return B(name)

	# A -> B -> C to work
	def work(self):
		b = self.get_b('b')
		c = b.get_c('c')
		c.work()

class B:
	def __init__(self, name):
		self.name = name
	def get_c(self, name):
		return C(name)


class C:
	def __init__(self, name):
		self.name = name
	def work(self):
		print('Done! by' + self.name)


a = A('a')
a.work()

You can find , At this time in A Called in C Related code , But obviously C It should be right A Hidden , in other words , We should make use of B To make the C Complete relevant work , and A Just contact B that will do :

class A:
	def __init__(self, name):
		self.name = name
	def get_b(self, name):
		return B(name)

	# A -> B -> C to work
	def work(self):
		b = self.get_b('b')
        # c = b.get_c('c')
		# c.work()
		b.work()

class B:
	def __init__(self, name):
		self.name = name
	def get_c(self, name):
		return C(name)
    def work(self):
        c = self.get_c('c')
        c.work()


class C:
	def __init__(self, name):
		self.name = name
	def work(self):
		print('Done! by' + self.name)


a = A('a')
a.work()a.work()

Besides , For the dependent , Dependents should minimize the exposure of internal specific processes and methods , And only provide users with a user-friendly and detail hidden method , It not only improves the encapsulation of classes , It can also improve the user experience :

class computer:
    # private methods
	def __stop_service(self):
		print('wait for stopping process...done!')

	def __poweroff(self):
		print('wait for power off...done!')

	def __shut_screen(self):
		print('screen is going to sleep...done!')

	def __save_data(self):
		print('writing back data...done!')

	# public 
	def shutdown(self):
		self.__stop_service()
		self.__save_data()
        self.__shut_screen()
		self.__poweroff()


if __name__ == '__main__':
	c = computer()
	c.shutdown()
    # c.__save_data() error
    # c.__stop_service() error

2.2 Class encapsulation :Capsulation

########################################################################################################
########################################################################################################
### ___ ____ ___ _______ ___ ___ #####
### / \ /\ | \ / \ | | | /\ | | / \ |\ | #####
### | / \ |____/ \___ | | | / \ | | | | | \ | #####
### | /----\ | \ | | | /----\ | | | | | \ | #####
### \___/ / \ | \___/ |_____| |_____ / \ | _|_ \___/ | \| ###
############################################################################################################
############################################################################################################

First , stay Python in , Encapsulation is just a convention , in other words , In fact, the internal variables of any object can be accessed externally in some way . For an ordinary variable , The outside can be accessed at will , such as :

class temp:
    
    var = 1
    
    # some definitions
        

This variable var It can be accessed freely from the outside .

Inaccessible type ,Python Two internal variables are agreed :

  • _varname: Variables with variable names starting with underscores
  • __varname: A variable whose name begins with a double underscore

for example :

class temp:
    
    var = 1
    
    def __init__(self):
        
        self._var = 2
        self.__var = 3
    
    # other definitions


t = temp()
print(t.var) # 1
print(t._var) # 2, You can still visit , Just an agreement 
print(t.__var) # error, Double underscores are not accessible 
print(t._temp__var) # 3,  But it can still be accessed through the dictionary , Go further  Python  Private is just an agreement , Access is not completely restricted 

2.3 Class polymorphism :Polymophism

class animal:
	def run(self):
		print('it is running')

class dog(animal):
	def run(self):
		print('dog is running')

class cat(animal):
	def run(self):
		print('cat is running')

if __name__ == '__main__':
	d = dog()
	d.run()

	c = cat()
	c.run()

	print(isinstance(d, dog)) # True
	print(isinstance(d, animal)) # True
	print(isinstance(c, animal)) # True
	print(isinstance(c, dog)) # False

3、 ... and 、 abstract class

  • Can't instantiate ( When there are abstract methods )
  • Through the function decorator @abstractmethod Set the corresponding function in the abstract class as the abstract function , Subclass must implement
from abc improt ABCMeta, abstractmethod

class animal(metaclass=ABCMeta):

	def__init__(self, name, age):
		self.name = name
		self.age = age
	@abstractmethod
	def run(self):
		pass

class dog(animal):

	def __init__(self, name, age):
		self.name = name
		self.age = age

	def run(self):
		print('a dog runs with four legs running')


class kangroo(animal):

	def __init__(self, name, age):
		self.name = name
		self.age = age

	def run(self):
		print('a kangroo runs with two legs jumping')


d = dog('dd', 3)
d.run()

k = kangroo('kk', 5)
k.run()

Through abstract classes :

  • Ensure that the subclass contains and implements the corresponding functions
  • Ensure the standardization of naming

copyright notice
author[Ice sky],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/02/202202021414478819.html

Random recommended