美文网首页
30.2-魔术方法—实例化(创建)、hash和equal

30.2-魔术方法—实例化(创建)、hash和equal

作者: BeautifulSoulpy | 来源:发表于2019-12-23 10:53 被阅读0次

面对人生各种处境,我们都有选择的能力。面对一件不幸的事件,你可以大发雷霆、怨天尤人,甚至责备所有的人,但事情却不会因为这些而丝毫改变。不幸的事,它会继续地伴着你往后的生活,让你背负着一生的痛苦活下去。相反如果能放下怨恨和惧怕,换一个角度看事情,那么事情也许就不会如想象中那么糟糕


总结:
1.原则上:key相同,集合中才会有去重效果;hash值相同代表在同一个房间;

1. 魔术方法***(非常重要)

在python学习中,往往你会看到有的名称前面和后面都加上了双下划线,例如initstrdocnew等,这种写法很特别,在python 中由这些名字组成的集合所包含的方法就叫做魔法方法,也叫做特殊方法。魔术方法在类或对象的某些事件出发后会自动执行;

分类:
创建、初始化与销毁;
_init_ 与 _del_
hash
bool
可视化
运算符重载
容器和大小
可调用对象
上下文管理
反射
描述器
其他杂项

Python提供的魔法方法

1.1 实例化
方法 意义
_new_ 1.实例化一个对象,该方法需要返回一个值,如果该值不是cls的实例,则不会调用 _init_该方法永远都是静态方法 ; 2.返回值可有可无,无返回值时结果为None,3.在方法类返回时,不得采用当前类.new,因为这样会触发无限递归。可采用如下方式之一

new 方法的使用:
_new_ 方法很少使用,即使创建了该方法,也会使用 return super()._new_(cls) 基类object的 new 方法来创建实例并返回;

语言类编程的时候使用;

class A:pass
class B(A):pass
class C(B):
    def __new__(cls,*args,**kwargs):
        print(cls)
        print(args)
        print(kwargs)
        return super().__new__(cls)  # 返回一个实例new;
        # return 'abc'
    
    def __init__(self,name):
        self.name = name
        print('~~~~~~~~~~~~')
#     def __dir__(self):
#         return ('a','b','c','d')
#     def printdir(self):
#         print(dir(),'~~~~~~')
c = C('tom')
print(dir(c.__dict__))
print('-'*79)
print(sorted(dir(c)))
#---------------------------------------------------------------------------------------------------------
<class '__main__.C'>
('tom',)
{}
~~~~~~~~~~~~
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
-------------------------------------------------------------------------------
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']

1.2 hash(门牌号码) _可hash对象;

  1. hash int为 int本身 ; 非整形(字符、字符串等)为不同的值;值是没有规律;
  2. hash的幂等性:x不一样, hash 应该不一样;
  3. hash冲突: 不同的hash算法求值:不同的x求得同样的hash值;
    hash 空间充满的情况下,再往里面塞数,一定会出现hash值相同的情况;

类的实例可哈希;

方法 意义
_hash_ 内建函数 hash() 调用的返回值,返回一个整数。如果定义这个方法该类的实例就可hash。
_hash_ == None(类中加) 类对象不可hash
class A:pass
class B(A):pass
class C(B):
    def __hash__(self):   # hash门牌号码;
        return hash('abc')
    def __init__(self,name):
        self.name = name
        print('~~~~~~~~~~~~')
#     def __dir__(self):
#         return ('a','b','c','d')
#     def printdir(self):
#         print(dir(),'~~~~~~')
c = C('tom')
p = C('peter')
print(dir(c.__dict__))
print('-'*79)
print(hash(c))
print(hash(p))
#-----------------------------------------------------------------
~~~~~~~~~~~~
~~~~~~~~~~~~
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
-------------------------------------------------------------------------------
-8920692834900147942
-8920692834900147942

print(hash(c))
print(hash(p))
print('-'*60)
print((c,p))
print([c,p])
print({c,p})  # hash值相同没有去重效果;
#--------------------------------------------------------------------------------------
-8920692834900147942
-8920692834900147942
------------------------------------------------------------
(<__main__.C object at 0x000001DDE729B940>, <__main__.C object at 0x000001DDE729B978>)
[<__main__.C object at 0x000001DDE729B940>, <__main__.C object at 0x000001DDE729B978>]
{<__main__.C object at 0x000001DDE729B940>, <__main__.C object at 0x000001DDE729B978>}


总结:

  1. hash 值相同 相当于门牌号相同,两个人住一个房间;,没有去重效果;集合中key相同,才有去重复效果;
  2. 不同的hash算法hash冲突率不一样;
1.3 操作符重载
方法 含义
_eq_ (True 去重;False不去重) 对应==操作符,判断2个对象是否相等,返回bool值

_hash_ 方法只是返回一个hash值作为set的key,但是 去重 ,还需要 _eq_ 来判断2个对象是否相等。
hash值相等,只是hash冲突,不能说明两个对象是相等的。
因此,一般来说提供 _hash_ 方法是为了作为set或者dict的key,所以 去重 要同时提供_eq_ 方法。

hash 值相同+eq方法 有去重效果;
class A:pass
class B(A):pass
class C(B):
    def __hash__(self):   # hash门牌号码;
        return hash('abc')
    def __eq__(self,other):
        return True
    def __init__(self,name):
        self.name = name
        print('~~~~~~~~~~~~')
    def __repr__(self):
        return self.name
c = C('tom')
p = C('peter')
print('-'*60)
print((c,p))
print([c,p])
print({c,p})  # hash值相同也 可以去重+eq方法;
#-------------------------------------------------------------------------------------
~~~~~~~~~~~~
~~~~~~~~~~~~
------------------------------------------------------------
(tom, peter)
[tom, peter]
{tom}

原则上:key相同,才会有去重效果;hash值相同代表在同一个房间;

可不可以hash 验证

有eq在,hash等于None;
eq=false ,可hash;
eq=True,不可hash;

不可hash对象isinstance(p1, collections.Hashable)一定为False

import collections
print(isinstance(c,collections.Hashable))
#--------------------------------------------------------------
True
C:\ProgramData\Miniconda3\lib\site-packages\ipykernel_launcher.py:2: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working

相关文章

  • python 标准库学习笔记《四》

    魔术方法 __ new __ 创建实例对象 __ init __ 将传入的参数用于初始化实例对象 Notes:...

  • __init__方法

    init是为实例对象添加属性的一个方法,也叫构造器、魔术方法。 举个例子,我们创建了一个学生类,实例化三个学生,如...

  • NSString

    <1>常用创建方法//实例化方法创建 (instancetype)initWithString:(NSString...

  • java之了解

    访问实例变量和方法 通过已创建的对象来访问成员变量和成员方法,如下所示: /* 实例化对象*/ ObjectRef...

  • java NIO 网络

    ServerSocketChannel open方法:抽象类,不能直接new实例化,可使用open方法创建实例,即...

  • ##Python面向对象编程(一)

    类和实例 关键字: Class 初始化方法 (______init______) 可以在创建实例的时候绑定属性 注...

  • 关于spring,总结了一篇上万字的图文笔记,不管你工作几年都应

    spring bean的实例化 构造器实例化 静态工厂实例化 容器创建对象,不直接调用对象构造方法,而是调用静态工...

  • Python基础018--类的创建及实例化、类继承

    类的创建以及实例化、类继承 类的创建以及实例化定义:用来描述具有相同的属性和方法的对象的集合;它定义了该集合中每个...

  • Java 基础

    类和对象 对象:对象是类的一个实例,有状态和行为。 创建对象:声明,new 实例化,调用构造方法初始化对象。 类:...

  • 问题:如何实例化ExecutorService

    问题 如何实例化ExecutorService 答案 ExecutorService的创建 使用工厂方法创建Exe...

网友评论

      本文标题:30.2-魔术方法—实例化(创建)、hash和equal

      本文链接:https://www.haomeiwen.com/subject/oegznctx.html