Python百日百行代码挑战(day1,python技能树中类的练习)


最近在复现论文,做实验等等的过程中,深深感觉到自己的代码水平太差了,所以才有了这么一个想法,准备坚持一百天,每天看懂or写出来100行代码,尽量做到不重复,以此来增进一下python水平和编码思维习惯,每天的素材都是自己随机找到的,今天第一天,代码素材来源于csdn的python技能树的联系。

练习题

练习题一

本次练习一为Python入门技能树-基础语法-类-第二题。先看一下题目要求:
继承第一问的要求,完成你说我猜的小游戏,以下是示例输出:
猜一猜下半句是什么? hello -> :world
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? monkey -> :king
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? tomorrow -> :is another day
你太厉害了,这都能猜得到!+10分!
猜一猜下半句是什么? good -> :a
哈哈,肯定猜不到得啦:good->bye,扣除2分!
游戏结束,你本次游戏得分: 28

以下是题目所给出的代码部分

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()

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))

其中import的是这部分:

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()

选项为:
A:

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

B:

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)

C:

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

D:

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)

好,通过题目要求可以看到,本题要求实现HashKeyValueSet类当中的hset函数。首先对程序进行分析,该方法实现了什么功能。通过if name == ‘main’:部分,可以看到实例化过后的对象调用了四次该方法,通过后面的输入可以判断得到,该方法实现的功能为初始化题库,因此在解题过程中,重点要看ABCD四个选项中是否实现这一功能。

对A选项的分析
A选项就是错的,这个错的相当明显,就是在get函数里面,传入了太多的值。get函数出现在KeyValueSet的定义部分里面,很显然这里只允许传入一个值,但是A选项给了三个,完了程序就会报错,这么报的:

get() takes 2 positional arguments but 3 were given

对B选项的分析
相当正确的一个选项,看后面D的分析吧,这俩一样的,就是把一个句子写了两遍而已

对C选项的分析
这个代码可以说是相当的风骚啊,只写了一行,本来我以为这是个对的,运行完了才发现这玩意居然是错的(emmmm,难道说csdn当时选题的时候不怎么严谨?)。乍一看没什么问题,实际运行的时候才发现,字典中只剩下最后一个good bye!的键值对了。
我一开始想错了,我想的是,既然使得每一个key都等于了value(KeyValueSet中set这么说的),那么理应出现所有的组合,为什么值会被冲掉,后来发现每一个hash_key都是puzzle,所以在python看来,只是单纯修改了一下字典里面的值而已,所以最后只剩下了最后一次赋值的结果。

对D选项的分析
首先,该方法初始化了一个字典(在KeyValueSet部分),后面又定义了一个get函数,第一句话就用到 了这个函数,一开始,在该字典中没有任何值在里面,因此get出来的结果是一个None,返回为None,之后通过if语句,使得hash_set具有了初值,也就是一个字典,内容为第一次调用hset函数的hello和world。赋值结束以后,使用KeyValueSet类中的set方法,将hash_key和hash_set的内容结合起来,形成一个新的字典,此时大字典的value是一个小的字典。第二次调用hset方法的时候,里面已经有了初值,hast_set的内部存在值,跳转到else语句下面。(一开始我想着为啥不直接让hash_set等于一个键值对算了,后来发现这样的话会冲掉原来的值,这小破问题居然我都没想到,老了老了)。最终成功将题库加进来,perfect!

练习题二

本次练习二为Python入门技能树-基础语法-类-第三题

本题要求与上一题一致,代码部分如下:

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()

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()

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()

选项为:
A:

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

B:

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)

C:

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

D:

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)

对A选项的分析
该选项为错误选项,一开始我还没看出来有啥不对劲的,后来我才发现啊!在__init__函数里面,HashKeyValueSet定义了一个参数,叫做kvset,在test函数中,很显然可以看到这个参数就是KeyValueSet这个类啊!!而A选项,这玩意调动了KeyValueSet这个类当中的方法,但是!必须要写kvset.,来表示是从另一个类中调用的,不然python很蒙圈的,就跟血小板似的,一脸懵逼地看着你,你说谁尴尬啊。
但是在这里补充一下,在学习过程中,官方给出了这样一个资料代码:

class School:
    def __init__(self,name):
        self.teach_list = []
        self.name = name
    def zhaopin(self,teach):
        self.teach_list.append(teach)
    def shangke(self):
        for t in self.teach_list:
            t.work()

class Teacher:
    def __init__(self,name):
        self.name = name
    def work(self):
        print(f'{self.name}在上课')
lnh = School('老男孩')
t1 = Teacher('武Sir')
t2 = Teacher('太白')
t3 = Teacher('哪吒')
lnh.zhaopin(t1)
lnh.zhaopin(t2)
lnh.zhaopin(t3)
lnh.shangke()

通过实际测试,发现其确实可以运行,但是这里类之间却没有采用什么方法互相调用,这个原因是当你在创建t1等等的时候,t1本身就具有work这个工作的属性,因此才不需要额外的语句来说明,直接work()就行,但是本题中不一样,必须要表明这个方法是从另一个类中过来的才行。

对B选项的分析
这个和第二问其实没有什么差别,就是get了一下hash_key的值,和上一问的D分析逻辑上分析差不多,return的也没问题。和上一问的B有异曲同工之妙啊。需要强调的一点就是,当hash_set取到None的时候,必须在语句后面表明hash_set = {},这个作用是让python知道这玩意得是个字典,不然python看不懂后面那句话。

对C选项的分析
它甚至和上一问的C一模一样,就是因为类中调用了类多了一个kvset而已,还是一样的问题,把值给冲掉了。

对D选项的分析
和上一题的D一致,没啥好分析的了啊,同理也就是多了一个kvset。

本次训练收获总结

python中的get函数

这个函数就是为了取得字典中的某一个key对应的value,例子如下:

a = {'game1':'7 days to die','game2':'ARK','game3':'cfhd'}
print(a.get('game1'))

# 运行结果如下:
# 7 days to die

python中的format函数

识别输出语句中的大括号{},例子如下:

print('{} will improve {} skills'.format('I','python'))

# 输出结果
# I will improve python skills

python中神奇的符号->

这东西我复现论文的时候也没少见,一直很蒙圈,今天把这个例子静下心来写完才搞明白,这东西能够限定返回值的类型啊,本题中没有返回值,所以强行设置成了None。有的话设置成int啥的就行

对python中类的__init__()的理解

正经一点的话来说,他叫做构造函数。在Python语言中,所有以双下划线“__”包起来的方法,都统称为“魔术方法”。他就是其中的构造函数,用来初始化内部状态和参数,不过我肯定要用我自己的理解去解释这东西了,你创建这个类,你肯定得用,你要用你就得实际搞一个东西来用它,完了你想给这东西安排一下,你想咋安排就在这init里面设定,你要是不想安排,人万一不开心了不给你干活了咋整。大概就这样吧,表达能力不够,解释的不好

对python类中self的理解

self,就是你的实例对象,这两可以直接划等号了,比如你创建了一个动物的类,完了你让dog = Animal(),那程序里面的self就是dog,你给实例化的对象起个啥名,你的self就是啥意思。

其他总结

类和类有很多关系,除了熟知的子类用父类的东西以外,类和类之间的方法也可以互通。

  • 要不就是实例化一个对象,在另一个类中调用这个对象,因为实例化过了,所以这个对象就有了另一个类的方法,随便用。
  • 要不就是这个类直接调用另一个类,在__init__函数里面设定一个参数,用另一个类的方法的时候,把这个参数调用一下,也能用别的类的方法。

大概看了一下,这次的代码算上空格有109行,但是包括看教程举得那个例子,还有自己敲得一些东西,差不多下来有100行了,本次收获尚可吧。

防火防盗防诈骗

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值