Python技能树学习-类

题目一:Python类的基本使用(1)

下面的类封装了一组 set/get/keys 接口

# -*- coding: UTF-8 -*-
class KeyValueSet:
    def __init__(self) -> None:
        self.dict = {}

    def set(self, key, value):
        self.dict[key] = value

    def get(self, key):
        return self.dict.get(key)

    def keys(self):
        return self.dict.keys()

请你使用类 KeyValueSet 完成一个交互式命令行你想我猜游戏。支持:

  • 装载N个句子对
  • 你猜我想 闯关,输出上半句,等待用户猜测下半句
  • 如果猜中就累加10分,否则扣2分
  • 全部结束输出用户本次得分

我们编写一个新的class,内部通过组合KeyValueSet来支持上述功能,程序框架如下:

# -*- coding: UTF-8 -*-
class GuessSentenceGame:
    def __init__(self):
        self.kv = KeyValueSet()
        self.score = 0

    def setup(self, sentences):
        # TODO(You): 请在此编写装载逻辑
    
    def guess(self, first_word):
        # TODO(You): 请在此编写猜测结果,返回 err, value
    
    def run(self):
        self.score = 0
        for first_word in self.kv.keys():
            ret = input("猜一猜下半句是什么? {} -> :".format(first_word))
            err, value = self.guess(first_word)
            if err==0:
                print('你太厉害了,这都能猜得到!+10分!')
                self.score += 10
            else:
                self.score -= 2
                print('哈哈,肯定猜不到得啦:{}->{},扣除2分!'.format(first_word, value))
        print('游戏结束,你本次游戏得分:', self.score)

if __name__ == '__main__':

    sentences = [
        "hello world",
        'monkey king',
        'tomorrow is another day',
        "good bye"
    ]

    game = GuessSentenceGame()
    game.setup(sentences)
    game.run()

示例输出:

一个示例输出是:

猜一猜下半句是什么? hello -> :world
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? monkey -> :king
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? tomorrow -> :is another day
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? good -> :a
哈哈,肯定猜不到得啦:good->bye,扣除2分!
游戏结束,你本次游戏得分: 28

请选出下面的实现代码中,错误 的选项。

实现

 

# 第一种方法

class GuessSentenceGame:
    ...

    def setup(self, sentences):
        for sentence in sentences:
            cut_pos = sentence.find(' ')
            first_word, rest = sentence[0:cut_pos], sentence[cut_pos+1:].strip()
            self.kv.set(first_word, rest)

    def guess(self, first_word):
        value = self.kv.get(first_word)
        err = 0 if value else 1
        return err, value
# 第二种方法
class GuessSentenceGame:
    ...

    def setup(self, sentences):
        for sentence in sentences:
            self.append(sentence)

    def append(self, sentence):
        cut_pos = sentence.find(' ')
        first_word, rest = sentence[0:cut_pos], sentence[cut_pos+1:].strip()
        self.kv.set(first_word, rest)
    
    def guess(self, first_word):
        ret = self.kv.get(first_word)
        if ret is None:
            return 1, None
        else:
            return 0, ret

# 第三种方法
class GuessSentenceGame:
    ...

    def setup(self, sentences):
        for sentence in sentences:
            first_word, rest = self.parse_sentence(sentence)
            self.kv.set(first_word, rest)
    
    def parse_sentence(self, sentence):
        cut_pos = sentence.find(' ')
        return sentence[0:cut_pos], sentence[cut_pos+1:].strip()

    def guess(self, first_word):
        value = self.kv.get(first_word)
        return 0, value if value else 1, None

主要是代码结构和责任划分不同:

  • 方法一:直接设置键值对。在setup方法中,直接遍历句子列表,对每个句子执行分割操作,然后将分割得到的第一个单词和剩余部分设置为键值对。职责集中:所有操作(包括分割句子和设置键值对)都在setup方法内部完成,没有额外的方法调用。
  • 方法二:通过额外的方法处理句子。在setup方法中,通过调用append方法来处理每个句子。这种设计提供了更好的模块化。职责分离:append方法负责处理单个句子的分割和键值对设置,而 setup 仅负责遍历句子列表。
  • 方法三:进一步模块化。通过 parse_sentence 方法专门处理句子的解析。职责高度分离parse_sentence 负责句子的分割和格式化,setup 方法则只负责调用parse_sentence 和设置键值对。改进:guess 方法中的返回结构似乎有笔误,应该是 return 0, value if value else (1, None),这样就统一了返回格式和清晰地处理了空值情况。

错误答案分析

class GuessSentenceGame:
    ...

    def setup(sentences):
        for sentence in sentences:
            cut_pos = sentence.find(' ')
            self.kv.set(sentence[0:cut_pos], sentence[cut_pos+1:].strip())
        
    def guess(first_word):
        self.kv.get(first_word)
        return 0, value if value else 1, None

# 定义缺少'self'参数

# 在guess方法中,变量value未定义

# 返回值格式问题

更改后代码:

class GuessSentenceGame:
    ...

    def setup(self,sentences):
        for sentence in sentences:
            cut_pos = sentence.find(' ')
            self.kv.set(sentence[0:cut_pos], sentence[cut_pos+1:].strip())
        
    def guess(self,first_word):

        value = self.kv.get(first_word)

        return (0, value) if value else (1, None)

 

题目二:Python类的基本使用(2)

在上一题的基础上。通过类的集成,可以扩展原有的类。例如继承KeyValueSet容器类,扩展功能,支持类似redis的 hset/hget/hkeys 扩展接口

基本代码框架如下

# -*- coding: UTF-8 -*-
from key_value_set import KeyValueSet

class HashKeyValueSet(KeyValueSet):
    def __init__(self) -> None:
        super().__init__()

    def hset(self, hash_key, key, value):
        # TODO(You): 请在此实现 hset 方法

    def hget(self, hash_key, key):
        hash_set = self.get(hash_key)
        if hash_set is None:
            return None
        else:
            return hash_set.get(key)

    def hkeys(self, hash_key):
        hash_set = self.get(hash_key)
        if hash_set is None:
            return []
        else:
            return hash_set.keys()

用例如下:

# -*- coding: UTF-8 -*-
if __name__ == '__main__':
    hashset = HashKeyValueSet()

    hashset.hset('puzzle', 'hello', 'world!')
    hashset.hset('puzzle', 'monkey', 'king!')
    hashset.hset('puzzle', 'tomorrow', 'is another day')
    hashset.hset('puzzle', 'good', 'bye!')

    keys = hashset.hkeys('puzzle')
    for key in keys:
        ret = input("猜一猜下半句是什么? {} -> :".format(key))
        value = hashset.hget('puzzle', key)
        if ret == value:
            print('你太厉害了,这都能猜得到!')
        else:
            print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))

实现

# 第一种方法

self.set(hash_key, {key:value})


# 第二种方法

hash_set = self.get(hash_key)
if hash_set is None:
    hash_set = {key:value}
else:
    hash_set[key] = value

self.set(hash_key, hash_set)

# 第三种方法

hash_set = self.get(hash_key)
if hash_set is None:
    hash_set = {key:value}
    self.set(hash_key, hash_set)
else:
    hash_set[key] = value
    self.set(hash_key, hash_set)
  • 方法一:直接设置给定的hash_key到一个新的字典,其中只包含单一的键值对{key: value}。如果该hash_key之前已经存在且包含其他键值对,那么这些键值对将被新的字典覆盖。这种方法会导致数据丢失,除非每次只想维持一个键值对。
  • 方法二(最优):首先检查hash_key是否已经存在,如果不存在,创建一个新的字典并设置该键值对。如果存在,就在已有的字典中添加或更新键值对,并重新设置到hash_key。保证了数据的完整性,并能正确地更新或添加键值对。
  • 方法三:与第二种类似,但在每个条件分支中都调用了self.set。效果与第二种方法相同,但稍微增加了代码的冗余,因为在hash_set已经存在的情况下,可以仅更新字典而不是每次都调用self.set

错误答案分析

hash_set = self.get(hash_key,{key:value})
self.set(hash_key, hash_set)

# 不能正确地处理键值对的更新,还可能导致混淆,看起来像是在尝试更新或设置值,实际上并没有这么做。正确的做法是明确检查hash_key是否存在,如方法二所示,然后根据情况更新或添加键值对,并确保这些更改反映到存储结构中。

 

题目三:Python类的基本使用(3)

基于第1题,还可以通过类的组合,使用组合而非继承实现类的扩展,支持类似 redis 的 hset/hget/hkeys 扩展接口。

相比于本节第2题,下面代码使用组合的方式复合KeyValueSet的功能,从而实现HashKeyValueSet。

# -*- coding: UTF-8 -*-
from key_value_set import KeyValueSet

class HashKeyValueSet:
    def __init__(self, kvset) -> None:
        super().__init__()
        self.kvset = kvset

    def hset(self, hash_key, key, value):
        # TODO(You): 请在此添加代码

    def hget(self, hash_key, key):
        hash_set = self.kvset.get(hash_key)
        if hash_set is None:
            return None
        else:
            return hash_set.get(key)

    def hkeys(self, hash_key):
        hash_set = self.kvset.get(hash_key)
        if hash_set is None:
            return []
        else:
            return hash_set.keys()

类HashKeyValueSet的用例如下:

def test():
    hashset = HashKeyValueSet(KeyValueSet())

    hashset.hset('puzzle', 'hello', 'world!')
    hashset.hset('puzzle', 'monkey', 'king!')
    hashset.hset('puzzle', 'tomorrow', 'is another day')
    hashset.hset('puzzle', 'good', 'bye!')

    keys = hashset.hkeys('puzzle')
    for key in keys:
        ret = input("猜一猜下半句是什么? {} -> :".format(key))
        value = hashset.hget('puzzle', key)
        if ret == value:
            print('你太厉害了,这都能猜得到!')
        else:
            print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))

if __name__ == '__main__':
    test()

实现

# 第一种方法

hash_set = self.kvset.get(hash_key)
if hash_set is None:
    hash_set = {}
    hash_set[key] = value
    self.kvset.set(hash_key, hash_set)
else:
    hash_set[key] = value
    self.kvset.set(hash_key, hash_set)


# 第二种方法

self.kvset.set(hash_key, {key: value})

# 第三种方法

hash_set = self.kvset.get(hash_key)
if hash_set is None:
    hash_set = {key: value}
else:
    hash_set[key] = value
self.kvset.set(hash_key, hash_set)

在处理数据更新和键值对保存的方式上有所不同:

  • 方法一:首先检查hash_key是否已存在。如果不存在,则创建一个新的字典,并添加键值对,然后保存。如果存在,则在现有的字典中添加或更新键值对,并重新保存。这种方法保证了数据的完整性,并且正确处理了新旧键值对的添加和更新。
  • 方法二:每次调用时都会创建一个只包含单个键值对的新字典,并将其设置为hash_key的值。这会导致hash_key原有的数据被覆盖,如果hash_key下已经存储了其他键值对,那么这些数据将丢失。这种方法适用性有限,只有在确定不需要旧数据时才适用。
  • 方法三(最优):与第一种方法类似,但更简洁。它检查hash_key是否存在,然后相应地创建新字典或更新现有字典,最后保存。这种方法既保留了数据完整性,也有效地管理了新旧数据的更新。。

错误答案分析

self.set(hash_key, {key: value})

# 主要问题在于它不考虑已存在的数据,直接覆盖整个值

 

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python技能是CSDN提供的一个系统化、面向实战的学习环境,旨在帮助用户从初学者成长为合格的Python工程师。技能整理了关于Python领域的知识点,并从CSDN的海量数据中不断更新高质量内容。除了传统的阅读学习技能还为每个知识点提供了相应的练习题,帮助用户通过练习不断提升自己的技能,直至精通。初学者可以通过学习技能来获得CSDN的技能认证。正在学习Python的人可以尝试技能上的练习题,以了解自己的掌握程度。而对于Python领域的专家,他们可以给CSDN提供意见,并贡献高质量的文章。Python技能学习方式是通过阅读学习和练习题相结合。当然,随着人工智能时代的到来,越来越多的人开始学习Python,而Python技能则提供了全面、详细的学习内容,包括Python基础、Python进阶、前端、数据库、django、flask、数据分析和机器学习等多个模块,帮助大家全面学习和了解Python语言。123 #### 引用[.reference_title] - *1* *2* [Python之深入解析Python技能的测评分析](https://blog.csdn.net/Forever_wj/article/details/120610403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [Python技能](https://blog.csdn.net/CSDNedu/article/details/124011216)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值