📜  了解Python 3中的代码重用和模块化

📅  最后修改于: 2020-05-09 12:22:35             🧑  作者: Mango

什么是面向对象编程(OOP)?

OOP是一种基于“对象”概念的编程范例,其中可能包含字段形式的数据,通常称为属性; 以及程序形式的代码(通常称为方法)。 

对象具有称为属性的特征,并且可以通过其方法来完成各种事情。 OOP的最大特点是对象之间如何良好地交互,甚至在将来可以成型,这使它们对开发人员非常友好,可扩展,随时间变化,进行测试等等。

什么是模块化?

模块化是指先制作多个模块,然后将它们链接并组合以形成一个完整的系统的概念(即,将软件/ Web应用程序划分为较小模块的程度称为模块化)。 模块化实现了可重用性,并将重复性降至最低。

目的:学习面向对象的编程-模块化。 我们如何将代码的某些部分转换为库,以便任何人都可以将其用作将来的参考。 使代码模块化将实现重用性并最大程度减少重复。
依赖项: pygame
简介:我们将制作一个小型游戏(不是真正的游戏),而是一个环境和其中的一些对象。 我们将尝试使环境成为静态,并使对象(在我们的情况下为blob)模块化。 我们将利用PyGame,因为它为我们提供了一种简单的方式来直观地可视化我们在做什么和正在构建什么,因此我们可以看到我们的对象在运行。 我们要做的是构建Blob World,该世界由演员组成,称为Blob。 不同的Blob具有不同的属性,并且Blob需要在其Blob World环境中起作用。 通过这个示例,我们将能够说明模块化。

我们将学习过程分为两个阶段。

  1. 创建环境和blob
  2. 了解模块化

仓库(Github): 源代码
BLOB WORLD(Python代码) 

 import pygame
  random import
  STARTING_BLUE_BLOBS = 10
  STARTING_RED_BLOBS = 3
  WIDTH = 800
  HEIGHT = 600
  WHITE = ( 255 )
  BLUE = ( 255 )
  RED = ( 255 )
  game_display = pygame.display.set_mode((WIDTH, HEIGHT))
  pygame.display.set_caption( "Blob World" )
  clock = pygame.time.Clock()
  Blob: class Blob:
      def __init__( self , color):
          self .x = random.randrange( 0 , WIDTH)
          self .y = random.randrange( 0 , HEIGHT)
          self .size = random.randrange( 8 )
          self .color = color
      def move( self ):
          self .move_x = random.randrange( .move_x )
          self .move_y = random.randrange( .move_y )
          self .x + = self .move_x
          self .y + = self .move_y
          if self .x < 0 : self .x = 0
          elif self .x > WIDTH: self .x = WIDTH
          if self .y < 0 : self .y = 0
          elif self .y > HEIGHT: self .y = HEIGHT
  def draw_environment(blob_list):
     game_display.fill(WHITE)
      for blob_dict in blob_list:
          for blob_id in blob_dict:
              blob = blob_dict[blob_id]
             pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size)
             blob.move()
     pygame.display.update()
  def main():
      blue_blobs = dict ( enumerate ([Blob(BLUE) i in range (STARTING_BLUE_BLOBS)])) ([Blob(BLUE) (STARTING_BLUE_BLOBS)]))
      red_blobs = dict ( enumerate ([Blob(RED) i range ([Blob(RED) (STARTING_RED_BLOBS)]))
      while True :
          for pygame.event.get(): event pygame.event.get():
              if event.  type = = pygame.QUIT:
                 pygame.quit()
                 quit()
         draw_environment([blue_blobs,red_blobs])
          clock.tick( 60 )
  if __name__ = = '__main__' __name__ '__main__' :
     main()

PART(1/2):Blob世界在这一部分中,我们正在创建一个简单的游戏环境以及其中的一些对象,因为可视化所创建的内容是学习编程的一种特殊方法。 此处介绍使用pygame创建blob世界(即其环境和对象)的说明。 我们需要了解的只是如何使我们的代码模块化。

PART(2/2):模块化在第二部分中,我们将了解面向对象编程的基本功能,即模块化。 到目前为止,至少在我们可以使用PyGame进行的范围内,我们还没有引入任何使该(BLOB WORLD 代码 )难以维护或难以扩展的东西。 如何使其模块化? 对此有一个非常简单的测试,让我们尝试将其导入!
为此,我们有两个文件。 让我们复制Blob类并随机复制一个新文件: blob.py 

import random
class Blob:
    def __init__(self, color):
        self.x = random.randrange(0, WIDTH)
        self.y = random.randrange(0, HEIGHT)
        self.size = random.randrange(4,8)
        self.color = color
    def move(self):
        self.move_x = random.randrange(-1,2)
        self.move_y = random.randrange(-1,2)
        self.x += self.move_x
        self.y += self.move_y
        if self.x  WIDTH: self.x = WIDTH
        if self.y  HEIGHT: self.y = HEIGHT

回到我们的原始文件,让我们删除Blob类,然后从blob.py导入Blob。

import pygame
import random
from blob import Blob
STARTING_BLUE_BLOBS = 10
...

马上,在blob.py文件中,关于Blob类,我们得到了一个错误,其中有一些未定义的变量。 这绝对是编写类的问题,我们应尽量避免在类外部使用常量或变量。 让我们将这些值添加到__init__方法中,然后修改使用常量的所有部分。
因此,这是我们新的Blob类文件: blob.py

接下来,在我们的原始文件中,当我们调用Blob类时,期望这些参数具有一些值,因此您可以将它们添加到main函数中:

def main():
    blue_blobs = dict(enumerate([Blob(BLUE,WIDTH,HEIGHT) for i in range(STARTING_BLUE_BLOBS)]))
    red_blobs = dict(enumerate([Blob(RED,WIDTH,HEIGHT) for i in range(STARTING_RED_BLOBS)]))
    while True:
        ...

太好了,现在我们的Blob类至少可以导入了,因此它已经自然地模块化了! 另一个好主意是尝试给予正在使用您的代码的开发人员尽可能多的功能,并使您的类尽可能通用。 至少可以肯定使用此类给程序员更多的一个示例是blob大小的定义:

self.size = random.randrange(4,8)

为什么我们不想给程序员一个简单的方法来改变这些? 与x_boundary和y_boundary不同,我们不一定*需要*程序员为我们提供大小值,因为我们至少可以使用合理的起始默认值。 因此,我们可以执行以下操作: 

class Blob:
    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8)):
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color

现在,如果程序员想要更改大小,则可以更改,否则不必更改。 如果他们想要,我们可能还希望允许程序员修改Blob的速度: 

import random
class Blob:
    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.movement_range = movement_range
    def move(self):
        self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])
        self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])
        self.x += self.move_x
        self.y += self.move_y
        if self.x  self.x_boundary: self.x = self.x_boundary
        if self.y  self.y_boundary: self.y = self.y_boundary

们迫使Blob保持界线的行。 也许有一些示例,我们希望Blob能够在视线范围内自由漫游? 当然! 这个边界代码有用吗? 程序员是否很想经常使用它? 当然! 但是,要么根本不编写代码,要么给它自己的方法,这样更有意义: 

import random
class Blob:
    def __init__(self, color, x_boundary, y_boundary, size_range=(4,8), movement_range=(-1,2)):
        self.size = random.randrange(size_range[0],size_range[1])
        self.color = color
        self.x_boundary = x_boundary
        self.y_boundary = y_boundary
        self.x = random.randrange(0, self.x_boundary)
        self.y = random.randrange(0, self.y_boundary)
        self.movement_range = movement_range
    def move(self):
        self.move_x = random.randrange(self.movement_range[0],self.movement_range[1])
        self.move_y = random.randrange(self.movement_range[0],self.movement_range[1])
        self.x += self.move_x
        self.y += self.move_y
    def check_bounds(self):
        if self.x  self.x_boundary: self.x = self.x_boundary
        if self.y  self.y_boundary: self.y = self.y_boundary

现在,程序员可以决定是否使用它。 您还可以在move方法中提供某种参数,如果为True,则将在其中强制执行边界。
因此,我们瞥见了如何使我们的Python代码模块化。