六 OOP使用类和映射简化设计

映射在类中的使用

  此文接上一篇文章;https://www.cnblogs.com/liveforlearn/p/15213046.html

  在一些情况下可以使用映射,而非elif条件语句链。用elif语句链表达的语句比较复杂。

  对于一些简单的情形,做同样的事情采用映射完成的代码可以更好的工作,而且代码的可读性更强。

  

  在此例中rank参数到对象时很容易的事情

  如果对字典方法get(),defaultdict()不熟悉的话,请看这篇文章:https://www.cnblogs.com/liveforlearn/p/15201713.html

# -*- ecoding: utf-8 -*-
# @ModuleName: relect_card
# @Function: 
# @Author: 甲壳虫~~~
# @Time: 2021/9/1 6:40
#@blog:https://www.cnblogs.com/liveforlearn

from lott_object_book.chapter1.samplest_demo import AceCard, NumberCard, \
    FaceCard
from lott_object_book.chapter1.constant_list import Club, Diamond, Heart, Spade

def card4(rank, suit):
    class_ = {1: AceCard, 11: FaceCard, 12: FaceCard, 13: FaceCard}.get(rank,
                                                                   NumberCard)
    return class_(rank, suit)

deck = [card4(rank, suit)
        for rank in range(14)
            for suit in (Club, Diamond, Heart, Spade)]
for i in deck:
    print(i.suit, i.rank, i.hard, i.soft, i.suit.name, i.suit.symbol)

  把rank映射为对象,然后再把rank值和suit值作为参数传入Card构造函数来创建Card实例。

  下面是使用defaultdict()方法实现的,rank映射为对象

from collections import defaultdict
defaultdict(lambda: NumberCard, {1: AceCard, 11: FaceCard, 12: FaceCard, 13: FaceCard})

  这里只是完成了rank映射为Card子类(AceCard, FaceCard, FaceCard, FaceCard)对象的映射。所以这个实现有一个明显的缺陷,在实例化的时候将缺少,从1到A和13到K的映射。

  当试图添加这块代码时将会遇到麻烦:

    defaultdict类默认构造函数必须是无参的。这里使用lambda构造函数作为常量的封装函数。

 

  修改映射逻辑:除了提供Card子类,还需要提供rank对象的的字符串结果。如何实现这两部分的映射

      • 可以建立两个并行的映射。此外并不推荐这种做法,后面的章节说明为什么这样做不值得:此处留超链接占位符!       
      • 可以映射一个二元组。也存在一些弊端。
      • 可以映射为partial()函数。
      • 也可以考虑修改类定义来完成映射的逻辑。后面介绍如何在子类中重写__init__()函数来完成这个方案:此处留超链接占位符!   

待补充。。。。

上一篇:PAT甲级1012


下一篇:哔哩哔哩热榜爬虫程序及数据处理