菜鸟初学python入门进阶第五节:面向对象,set与dict


上一篇的连接:菜鸟初学python入门进阶第四节:面向对象,自定义序列类


❤⭐🍦🍧🌈🌊🎉💄💻✨🎊🎏✨✨老铁萌球球点赞👍 评论📚
乱打的也可以

1.dict的abc继承关系🔥

dict属于map类型
先看看源码

from collections.abc import Mapping

点击abc,ctrl+b

from _collections_abc import *
from _collections_abc import __all__

ctrl+B进入all

__all__ = ["Awaitable", "Coroutine",
           "AsyncIterable", "AsyncIterator", "AsyncGenerator",
           "Hashable", "Iterable", "Iterator", "Generator", "Reversible",
           "Sized", "Container", "Callable", "Collection",
           "Set", "MutableSet",
           "Mapping", "MutableMapping",
           "MappingView", "KeysView", "ItemsView", "ValuesView",
           "Sequence", "MutableSequence",
           "ByteString",
           ]

看到"Mapping", "MutableMapping",dict属于"MutableMapping"(可修改mapping)
再来ctrl+B

class MutableMapping(Mapping):

其继承了mapping

class Mapping(Collection):

mapping也是继承collection,所以某种程度上和序列类型有很多操作方法一样

2.再谈isinstance🔥

isinstance(实例, 某种类型)
isinstance方法还可以判断继承链
我们不妨看看isinstance的描述

def isinstance(x, A_tuple): # real signature unknown; restored from __doc__
    """
    Return whether an object is an instance of a class or of a subclass thereof.
    
    A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to
    check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)
    or ...`` etc.
    """
    pass

返回实例是否是该类或该类其中某个子类的实例
但是

from _collections_abc import *
from _collections_abc import __all__

a = {}
print(isinstance(a, MutableMapping))

输出

True

a是一个字典,但是当我们去看dict的继承关系

class dict(object):

dict却基本没有继承任何东西
a并不是真正继承了mutablemapping,只是实现了其中一些魔法函数
isinstance实际上是调用了register。
如果我们去mutablemapping类的末尾,可以看到

MutableMapping.register(dict)

dict被先注册在了mutablemapping里,仿佛预先知道 mutablemapping一定会有一个子类是dict。
这种方法不同于继承,这是注册,先注册将要有的子类,再在别处写该具体子类,子类不需要再继承基类,只需要实现注册该子类的基类中的魔法函数(协议)即可。
这和继承是反过来的。
不管是继承还是注册,这几个类都被连在了一条链上。
isinstance就是找这条链上的类。

3.dict的一些常见操作🔥

我们可以通过上述方法去查看dict的操作。
鉴于dict其实是用c语言写的,我们如果用pycharm,还是可以看到其用python的方式为我们展现了dict的描述和操作。这并不是真的逻辑,只是用代码的方式为我们展现文档。

常用操作如

a = {"a": {"b": "c"}}
a.clear()

就不赘述了。

浅拷贝和深拷贝:

a = {"a": {"b": "c"}}
b = a.copy()
import copy
c = copy.deepcopy(a)

b是浅拷贝的结果,实际上只是用一个新的指针指向原地址
c是深拷贝,是真正弄了一个备份,可以随意修改,不影响原来的数据

fromkeys方法:
这是个静态方法,可以为可迭代的对象增加值,并返回一个字典

l = ['a', 'b']
d = dict.fromkeys(l, 2)
print(d)

输出

{'a': 2, 'b': 2}

get方法:
xxx = xx.get(“key”,默认值)

items方法:

a = {"a": {"b": "c"}, "d": "e"}
for key, value in a.items():
    print(key, value)

输出

a {'b': 'c'}
d e

setdefault方法:
不仅将值取出来,还加进原字典里

a = {"a": {"b": "c"}, "d": "e"}
j = a.setdefault("f", 'g')
print(j)
print(a)

输出

g
{'a': {'b': 'c'}, 'd': 'e', 'f': 'g'}

update方法:
有点像extend,放可迭代的字典就行

a = {"a": {"b": "c"}, "d": "e"}
a.update(aa="aa",bb="bb",cc="cc",dd="dd")
print(a)

输出

{'a': {'b': 'c'}, 'd': 'e', 'aa': 'aa', 'bb': 'bb', 'cc': 'cc', 'dd': 'dd'}

4.dict的一些子类🔥

UserDict
鉴于dict其实是用c语言写的,不建议继承dict或list
一般使用继承UserDict

from collections import UserDict
class nDict(UserDict):
    def __setitem__(self, key, value):
        super().__setitem__(key, value)

defauldict

from collections import defaultdict
class defaultdict(dict):
    """
    defaultdict(default_factory[, ...]) --> dict with default factory
    
    The default factory is called without arguments to produce
    a new value when a key is not present, in __getitem__ only.
    A defaultdict compares equal to a dict with the same items.
    All remaining arguments are treated the same as if they were
    passed to the dict constructor, including keyword arguments.
    """

defaudict主要是重写了missing方法,dict属于mutablemapping,mutablemapping里面的getitem方法会调用missing方法。
defaudict如果找不到键,会默认返回空列表

    def __missing__(self, key): # real signature unknown; restored from __doc__
        """
        __missing__(key) # Called by __getitem__ for missing key; pseudo-code:
          if self.default_factory is None: raise KeyError((key,))
          self[key] = value = self.default_factory()
          return value
        """
        pass

使用:

from collections import defaultdict
a = {"a": {"b": "c"}, "d": "e"}
b = defaultdict(dict, a)
c = b['sb']
print(c)

输出

{'a': {'b': 'c'}, 'd': 'e', 'aa': 'aa', 'bb': 'bb', 'cc': 'cc', 'dd': 'dd'}
{}

5.set与frozenset🔥

集合与不可变集合。
集合无序,不重复。
frosenset没有add方法。
set有很多的方法,也实现了很多魔法函数,性能很高。
简单方法看文档即可

6.dict与set的实现原理🔥

dict查找的性能远远大于list。在list中随着数据增大,查找时间增加,而在dict中查找时间不会增加。
dict实际上是个哈希表在这里插入图片描述
set也是哈希表
dict的key和set的值,都必须是可以哈希的。
而不可变对象都是可哈希的,如str、frosenset、tuple。
我们可以通过实现魔法函数hash来让自定义类返回特定的值,把自定义类变成可哈希的,再放到dict的key和set的值中。
dict的内存花销大,但找的快。
dict的储存顺序和元素添加顺序有关,且加入数据可能改变已有数据的顺序。


就到这里😙😙
下一篇的连接:菜鸟初学python入门进阶第六节:面向对象,引用、可变性与垃圾回收


❤⭐🍦🍧🌈🌊🎉💄💻✨🎊🎏✨✨d=====( ̄▽ ̄*)b

U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*UU•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值