资讯专栏INFORMATION COLUMN

Python超细腻研究面向对象设计

89542767 / 367人阅读

  面向对象设计是一类编程方式,此编程方式的落地式需要使用“类”和“目标”来达到,因此,面向对象设计本身就是对“类”和“目标”的应用,今日给大家介绍一下python面向对象设计开发设计及本质特征,感兴趣的小伙伴一起了解一下吧


  序言


  面向对象设计对新手而言不难理解但无法运用,尽管我们给大家汇总过面向对象战略部署方式(定义类、创建对象、给目标发信息),可是看似简单其实不简单。大量程序编写训练与阅读高质量的编码有可能是这一阶段最能够帮到大家的两件事。下面我们还是用经典实例来剖析面向对象设计的基础知识,并且也通过这个实例给大家讲解怎样利用以前学习过的Python专业知识。


  扑克牌游戏。


  表明:简洁明了考虑,我们自己的扑克牌仅有52扑克牌(并没有两王),手机游戏需要把52扑克牌发至4个游戏玩家手里,每个游戏玩家手里有13扑克牌,依照黑桃皇后、桃心、金边麦冬、格子顺序和等级从小到大排列,暂不完成别的的功效。


  应用面向对象设计方式,首先要从难题的需要中寻找目标并抽像出相对应的类,除此之外还需要寻找对象的属性与行为。自然,这件事并不是很艰难,我们要从市场需求的谈话中找到动词和名词,专有名词一般便是目标或是对象的属性,而形容词一般是对象个人行为。扑克牌游戏中最少应当有三种目标,各是牌、扑克牌和游戏玩家,牌、扑克牌、游戏玩家3个类并不是独立的。类及类的关系能够粗略地的分为is-a关系(传承)、has-a关系(关系)和use-a关系(依靠)。显然扑克牌胡牌是has-a关系,因为一副扑克有(has-a)52扑克牌;游戏玩家胡牌中间不但有关联性也有依存关系,因为游戏玩家手里有(has-a)牌并且游戏玩家用了(use-a)牌。


  牌的特性不言而喻,有颜色和等级。我们可以通过0到3的四个数字来意味着4种不一样花色,但这样的代码可读性会很糟糕,只要我们并不了解黑桃皇后、桃心、金边麦冬、格子跟0到3的数的相互关系。当一个自变量的选值仅有比较有限好几个选择项,大家可以用枚举类型。与C、Java等语言表达不一样的是,Python里没有申明枚举类型的关键词,可是能通过传承enum控制模块Enum类来建立枚举类型,编码具体如下。


  from enum import Enum
  class Suite(Enum):
  """花色(枚举)"""
  SPADE,HEART,CLUB,DIAMOND=range(4)


  依据上边的编码能够得知,界定枚举类型本身就是界定符号常量,如SPADE、HEART等。每个符号常量都是有与其相对应的值,谈道黑桃皇后就不用再数据0,而是以Suite.SPADE;同样,表明格子可以不数据3,而是以Suite.DIAMOND。留意,应用符号常量一定是好于应用字面上变量定义的,因为能够了解英语就能明白符号常量的内涵,编码的易读性会提高许多。Python里的枚举类型是可迭代种类,简单来说就是能将枚举类型放在for-in循环中,先后取下每个符号常量及其相对应的值,具体如下。


  class 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']
  #根据牌的花色和点数取到对应的字符
  return f'{suites[self.suite.value]}{faces[self.face]}'


  实施上边的编码会在player.arrange()那边发现异常,因为Player的arrange方法用了目录的sort对游戏玩家手里的牌进行筛选,排列必须较为2个Card对象尺寸,而<操作符又无法直接应用于Card类型,因此出现了TypeError出现异常,出现异常信息为:'<'notsupportedbetweeninstancesof'Card'and'Card'。


  card1=Card(Suite.SPADE,5)
  card2=Card(Suite.HEART,13)
  print(card1,card2)#♠5♥K


  为了能解决这些问题,我们能对Card类的编码稍加改动,促使2个Card目标也可以用<开展大小的小较为。这儿使用技术性叫函数重载,Python时要完成对<操作符的轻载,必须在类中加入1个名叫__lt__的魔术师方式。显然,魔术师方式__lt__中的lt是英文单词“lessthan”的简称,依此类推,魔术师方式__gt__相匹配>操作符,魔术师方式__le__相匹配<=操作符,__ge__相匹配>=操作符,__eq__相匹配==操作符,__ne__相匹配!=操作符。


  修订后的Card类编码具体如下。


  import random
  class Poker:
  """扑克"""
  def __init__(self):
  #通过列表的生成式语法创建一个装52张牌的列表
  self.cards=[Card(suite,face)for suite in Suite
  for face in range(1,14)]
  #current属性表示发牌的位置
  self.current=0
  def shuffle(self):
  """洗牌"""
  self.current=0
  #通过random模块的shuffle函数实现列表的随机乱序
  random.shuffle(self.cards)
  def deal(self):
  """发牌"""
  card=self.cards[self.current]
  self.current+=1
  return card
  property
  def has_next(self):
  """还有没有牌可以发"""
  return self.current<len(self.cards)


  薪资发放系统软件。


  规定:某企业有三大类的职工,各是业务经理、程序猿和销售人员。必须制作一个薪资发放系统软件,依据所提供的员工档案进行计算职工的月工资。在其中,业务经理的月工资是固定不动15000元;程序猿按上班时间(以钟头为基准)付款月工资,一小时200元;销售人员的月工资由1800元基本工资再加上销售总额5%的抽成两个部分组成。


  poker=Poker()
  poker.shuffle()
  print(poker.cards)


  依据对于该市场需求的剖析,能够得知业务经理、程序猿、销售人员全是职工,有共同的特性与行为,那我们可以直接制作一个名叫Employee的成员变量,然后通过传承的形式从这一成员变量派长出业务经理、程序猿和销售人员3个派生类。显然,后续编码不容易建立Employee类对象,只要我们更需要的是实际的职工目标,并且这个类能够设计为专门用来传承的内部类。Python里没有界定内部类的关键词,可是能通过abc控制模块中名叫ABCMeta的元类来衡量内部类。有关元类专业知识,后边的课堂中会有专业的解读,这儿无需太过纠结这一概念,记牢使用方法就可以。


  class Player:
  """玩家"""
  def __init__(self,name):
  self.name=name
  self.cards=[]
  def get_one(self,card):
  """摸牌"""
  self.cards.append(card)
  def arrange(self):
  self.cards.sort()


  在后面的职工类中,有个名叫get_salary的方式用以结款月工资,但由于都还没断定什么类型职工,因此结款月工资虽是职工的公众个人行为但这却不能够完成。针对暂且不能完成的办法,大家能使用abstractmethod装饰器把它申明为抽象类,所说抽象类便是仅有申明无法实现的办法,申明用这种方法是为了给派生类去重新写过用这种方法。接下来代码展示了怎样从职工类派长出业务经理、程序猿、销售人员这几个派生类及其派生类怎样重新写过成员变量的抽象类。


  class Manager(Employee):
  """部门经理"""
  def get_salary(self):
  return 15000.0
  class Programmer(Employee):
  """程序员"""
  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):
  """销售员"""
  def __init__(self,name,sales=0):
  super().__init__(name)
  self.sales=sales
  def get_salary(self):
  return 1800+self.sales*0.05


  上边的Manager、Programmer、Salesman3个类都传承自Employee,3个类都各自重新写过了get_salary方式。重新写过便是派生类对成员变量现有的方式再次作出完成。想必大家早已察觉到了,3个派生类中的get_salary不尽相同,因此用这种方法在程序执行的时候会造成多态性个人行为,多态性简单来说就是启用同样的方式,不同类型的派生类目标做不同类型的事儿。


  poker=Poker()
  poker.shuffle()
  players=[Player('东邪'),Player('西毒'),Player('南帝'),Player('北丐')]
  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)


  我们可以通过下边的编码来实现这一薪资发放系统软件,因为程序猿和销售人员必须各自上传当月工作时间和销售总额,因此在下边的编码中用了Python内嵌的isinstance函数来判断职工对象种类。我们之前讲过的type函数也能识别对象种类,但是isinstance函数更加强大,因为它可以判断出一个目标是不是某个传承结构下的子类型,你可以简答的理解为type函数是对对象类型的精准匹配,而isinstance函数是对对象类型的模糊匹配。


  from abc import ABCMeta,abstractmethod
  class Employee(metaclass=ABCMeta):
  """员工"""
  def __init__(self,name):
  self.name=name
  abstractmethod
  def get_salary(self):
  """结算月薪"""
  pass
  总结
  class 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']
  #根据牌的花色和点数取到对应的字符
  return f'{suites[self.suite.value]}{faces[self.face]}'
  def __lt__(self,other):
  #花色相同比较点数的大小
  if self.suite==other.suite:
  return self.face<other.face
  #花色不同比较花色对应的值
  return self.suite.value<other.suite.value


  面向对象的编程思想非常的好,也符合人类的正常思维习惯,但是要想灵活运用面向对象编程中的抽象、封装、继承、多态需要长时间的积累和沉淀,这件事情无法一蹴而就,属于“路漫漫其修远兮,吾将上下而求索”的东西。


  上述文章就给大家介绍完毕,希望可以给大家带来帮助。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128848.html

相关文章

  • [零基础学python]关于类的初步认识

    摘要:反对者在某些领域对此予以否认。下面再引用一段来自维基百科中关于的历史。类的更严格的定义是由某种特定的元数据所组成的内聚的包。类还可以有运行时表示形式元对象,它为操作与类相关的元数据提供了运行时支持。 在开始部分,请看官非常非常耐心地阅读下面几个枯燥的术语解释,本来这不符合本教程的风格,但是,请看官谅解,因为列位将来一定要阅读枯燥的东西的。这些枯燥的属于解释,均来自维基百科。 1、问题...

    王岩威 评论0 收藏0
  • 拼多多的搜索的参数anti_content怎么破

    摘要:这里就可以看到我们需要找的参数了,但是这里已经生成了,我们可以直接查看右边的调用栈经过多次查看,可以很容易就发现这个地方有点东西,立即下断点这时我们可以先去掉断点,然后刷看查看,获取不断点下一个断点直到运行结束再滑动到下一页即可。 今天继续带来破解拼多多的 anti_content 参数破解,代码已经放在github上:https://github.com/SergioJune...(...

    everfight 评论0 收藏0
  • 拼多多的搜索的参数anti_content怎么破

    摘要:这里就可以看到我们需要找的参数了,但是这里已经生成了,我们可以直接查看右边的调用栈经过多次查看,可以很容易就发现这个地方有点东西,立即下断点这时我们可以先去掉断点,然后刷看查看,获取不断点下一个断点直到运行结束再滑动到下一页即可。 今天继续带来破解拼多多的 anti_content 参数破解,代码已经放在github上:https://github.com/SergioJune...(...

    tulayang 评论0 收藏0
  • 学习Python:做数据科学还是网站开发?

    摘要:属于前一种,而且日益被用于数学计算机器学习和多种数据科学应用。近来,由于拥有多个针对机器学习自然语言处理数据视觉化数据探索数据分析和数据挖掘的插件,丰富的数据科学生态体系得到了较大的发展,甚至有将数据科学社区化的趋势。 译者注:本文的英文原文地址是:Python for Data Science vs Python for Web Development,发布时间是10月29日。译者一...

    neu 评论0 收藏0
  • 小型的编程项目有哪些值得推荐?这本神书写了 22 个,个个了不得

    摘要:电子表格使用语言电子表格是办公软件的必备,我们最熟知的是微软的。文中用框架来实现一个简单的电子表格,所用代码仅行。 showImg(https://segmentfault.com/img/remote/1460000019770011); 本文原创并首发于公众号【Python猫】,未经授权,请勿转载。 原文地址:https://mp.weixin.qq.com/s/Ob... 今天,...

    haitiancoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<