程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python Basics: object oriented [case practice]

編輯:Python

Preface

Object oriented programming is not difficult for beginners to understand, but it is difficult to apply , Although we have summarized the object-oriented three-step method for you ( Defining classes 、 Create objects 、 Send messages to objects ), But easier said than done . A lot of programming practice and Read good code It may be the two things that can help you most at this stage . Next, we will analyze the knowledge of object-oriented programming through classic cases , At the same time, through these cases, I will explain how to use what I have learned before Python knowledge .

Catalog

  • Preface
    • Classic case 1: Poker game .
    • Classic case 2: Payroll system .
  • summary

Classic case 1: Poker game .

explain : Simplicity , Our poker is only 52 card ( There is no king or king ), The game needs to 52 Cards are dealt to 4 Players' hands , Each player has 13 card , According to spades 、 Red hearts 、 Grass flower 、 The order of the squares and the number of points are arranged from small to large , Do not realize other functions for the time being .

  • Using object-oriented programming methods , First, you need to find the object from the requirements of the problem and abstract the corresponding class , In addition, find the properties and behavior of the object . Of course , This is not particularly difficult , We can find nouns and verbs from the description of requirements , Nouns are usually objects or attributes of objects , Verbs are usually the actions of objects . There should be at least three types of objects in a poker game , They are cards 、 Poker and players , card 、 Poker 、 The three categories of players are not isolated . The relationship between classes can be roughly divided into is-a Relationship ( Inherit )has-a Relationship ( relation ) and use-a Relationship ( rely on ). Obviously poker and cards are has-a Relationship , Because a deck of poker has (has-a)52 card ; There are not only correlations but also dependencies between players and cards , Because players have (has-a) And the player used (use-a) card .

  • The nature of the card is obvious , There are decors and points . We can use 0 To 3 To represent four different designs and colors , But the readability of such code would be very bad , Because we don't know spades 、 Red hearts 、 Grass flower 、 Square heel 0 To 3 The corresponding relationship between the numbers of . If a variable has only a limited number of options , We can use enumeration . And C、Java The language difference is ,Python There is no keyword declaring enumeration type in , But it can be inherited enum Modular Enum Class to create enumeration types , The code is as follows .

from enum import Enum
class Suite(Enum):
""" Design and color ( enumeration )"""
SPADE, HEART, CLUB, DIAMOND = range(4)
  • You can see from the above code that , Defining an enumeration type is actually defining a symbolic constant , Such as SPADEHEART etc. . Each symbolic constant has a corresponding value , In this way, the spades can be expressed without numbers 0, It's about using Suite.SPADE; Empathy , It means that the square can be without numbers 3, It's about using Suite.DIAMOND. Be careful , Using symbolic constants is certainly better than using literal constants , Because I can understand the meaning of symbolic constants by reading English , The readability of the code will be improved a lot .Python The enumeration type in is an iteratable type , Simply put, you can put the enumeration type into for-in In circulation , Take out each symbolic constant and its corresponding value in turn , As shown below .
for suite in Suite:
print(f'{
suite}: {
suite.value}')
  • Next, we can define the card class .
class Card:
""" card """
def __init__(self, suite, face):
self.suite = suite
self.face = face
def __repr__(self):
suites = ''
faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
# Get the corresponding character according to the design and color of the card and the number of points
return f'{suites[self.suite.value]}{faces[self.face]}'
  • You can use the following code to test Card class .
card1 = Card(Suite.SPADE, 5)
card2 = Card(Suite.HEART, 13)
print(card1, card2) # 5 K
  • Next we define the poker class .
import random
class Poker:
""" Poker """
def __init__(self):
# Create a package by using the list's generative syntax 52 A list of cards 
self.cards = [Card(suite, face) for suite in Suite
for face in range(1, 14)]
# current Attribute indicates the location of the deal 
self.current = 0
def shuffle(self):
""" Shuffle """
self.current = 0
# adopt random Modular shuffle Function to realize the random disorder of the list 
random.shuffle(self.cards)
def deal(self):
""" Licensing """
card = self.cards[self.current]
self.current += 1
return card
@property
def has_next(self):
""" There are no cards to deal """
return self.current < len(self.cards)

  • You can use the following code to test Poker class .
poker = Poker()
poker.shuffle()
print(poker.cards)
  • Define player class .
class Player:
""" The player """
def __init__(self, name):
self.name = name
self.cards = []
def get_one(self, card):
""" Touch the card """
self.cards.append(card)
def arrange(self):
self.cards.sort()
  • Create four players and hand the cards to the player .
poker = Poker()
poker.shuffle()
players = [Player(' Dongxie '), Player(' Western poison '), Player(' South Emperor '), Player(' North beggar ')]
for _ in range(13):
for player in players:
player.get_one(poker.deal())
for player in players:
player.arrange()
print(f'{
player.name}: ', end='')
print(player.cards)
  • Executing the above code will result in player.arrange() There is an exception , because Player Of arrange Method uses the... Of the list sort Sort the cards in the player's hand , Sorting requires comparing two Card Size of object , and < The operator cannot directly act on Card type , So there it is TypeError abnormal , The exception message is :'<' not supported between instances of 'Card' and 'Card'.

  • To solve this problem , We can Card Class code is slightly modified , Make two Card Objects can be used directly < Compare sizes . The technology used here is called Operator overloading ,Python To realize the < operator overloading , You need to add a class named __lt__ The magic of . Obviously , Magic methods __lt__ Medium lt It 's an English word “less than” Abbreviation , And so on , Magic methods __gt__ Corresponding > Operator , Magic methods __le__ Corresponding <= Operator ,__ge__ Corresponding >= Operator ,__eq__ Corresponding == Operator ,__ne__ Corresponding != Operator .

  • The modified Card The class code is as follows .

class Card:
""" card """
def __init__(self, suite, face):
self.suite = suite
self.face = face
def __repr__(self):
suites = ''
faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
# Get the corresponding character according to the design and color of the card and the number of points 
return f'{
suites[self.suite.value]}{
faces[self.face]}'
def __lt__(self, other):
# Compare the size of points with the same design and color 
if self.suite == other.suite:
return self.face < other.face
# Compare the values corresponding to different decors 
return self.suite.value < other.suite.value

explain : You can try to write a simple poker game based on the above code , Such as 21 Click game (Black Jack), The rules of the game can be found on the Internet .

Classic case 2: Payroll system .

requirement : There are three types of employees in a company , Department managers 、 Programmers and salesmen . We need to design a salary settlement system , Calculate the employee's monthly salary according to the employee information provided . among , The monthly salary of the Department Manager is fixed 15000 element ; Programmers work by hours ( In hours ) Pay monthly salary , Every hour 200 element ; The monthly salary of the salesperson is paid by 1800 Yuan base salary plus sales 5% A commission of two parts .

  • Through the analysis of the above requirements , It can be seen that the Department Manager 、 The programmer 、 Salespeople are employees , Have the same properties and behavior , So we can design a new one named Employee Parent class of , Then the Department Manager is derived from this parent class by inheritance 、 Programmers and salespeople are three sub categories . Obviously , Subsequent code will not create Employee Class object , Because what we need is a specific employee , So this class can be designed as an abstract class for inheritance .Python There are no keywords for defining abstract classes in , But it can go through abc Module named ABCMeta To define abstract classes . Knowledge of metaclasses , There will be special explanations in the later courses , There is no need to struggle with this concept , Just remember the usage .
from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
""" staff """
def __init__(self, name):
self.name = name
@abstractmethod
def get_salary(self):
""" Settle monthly salary """
pass
  • In the above employee class , There is one named get_salary This method is used to settle the monthly salary , But since it has not been determined what kind of employees it is , Therefore, although the settlement of monthly salary is a public behavior of employees, there is no way to achieve it here . For methods that cannot be implemented temporarily , We can use abstractmethod Decorator declares it as an abstract method , So-called An abstract method is a method that has only a declaration but no implementation , This method is declared so that subclasses can override it . The following code shows how to derive a department manager from an employee class 、 The programmer 、 Salesperson these three subclasses and how subclasses override the abstract methods of the parent class .
class Manager(Employee):
""" division manager """
def get_salary(self):
return 15000.0
class Programmer(Employee):
""" The programmer """
def __init__(self, name, working_hour=0):
super().__init__(name)
self.working_hour = working_hour
def get_salary(self):
return 200 * self.working_hour
class Salesman(Employee):
""" Salesperson """
def __init__(self, name, sales=0):
super().__init__(name)
self.sales = sales
def get_salary(self):
return 1800 + self.sales * 0.05
  • above ManagerProgrammerSalesman All three classes inherit from Employee, Each of the three classes overrides get_salary Method . Rewriting is a subclass's re - Implementation of an existing method of a parent class . I believe you have noticed , Of the three subclasses get_salary Each are not identical , So this method will produce when the program is running Polymorphic behavior , Polymorphism simply means Call the same method , Different subclass objects do different things .

  • We use the following code to complete the salary settlement system , As programmers and salespeople need to enter the working hours and sales volume of this month respectively , So in the following code we use Python Built in isinstance Function to determine the type of employee object . We talked about it before type Function can also identify the type of object , however isinstance Functions are more powerful , Because it can determine whether an object is a subtype of an inheritance structure , You can simply understand it as type Functions are exact matches of object types , and isinstance Function is a fuzzy matching of object types .

emps = [
Manager(' Liu bei '), Programmer(' Zhugeliang '), Manager(' Cao Cao '),
Programmer(' Emperor Xu '), Salesman(' Lyu3 bu4 '), Programmer(' Zhang liao '),
]
for emp in emps:
if isinstance(emp, Programmer):
emp.working_hour = int(input(f' Please enter {
emp.name} Working hours of this month : '))
elif isinstance(emp, Salesman):
emp.sales = float(input(f' Please enter {
emp.name} Sales this month : '))
print(f'{
emp.name} The salary of this month is : ¥{
emp.get_salary():.2f} element ')

summary

  • The idea of object-oriented programming is very good , It also conforms to the normal thinking habits of human beings , But if you want to make flexible use of abstraction in object-oriented programming 、 encapsulation 、 Inherit 、 Polymorphism takes a long time to accumulate and precipitate , It can't be done overnight , Belong to “ What a long long road! , I will go up and down ” Things that are .

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved