29面向对象4_dir-hash-bool-repr-str-创新互联-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

29面向对象4_dir-hash-bool-repr-str-创新互联

目录

为颍州等地区用户提供了全套网页设计制作服务,及颍州网站建设行业解决方案。主营业务为成都网站建设、网站设计、颍州网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

魔术方法分类:... 1

__dir__. 2

__hash__. 6

__bool__. 10

可视化... 11

魔术方法:

为编程提供便利,可大大提高编程效率;

pythonic;

特殊属性:

__name__,类、函数、方法等的名字,实例没有此属性;

__module__,类定义所在的模块名;

__class__,对象或类所属的类,如对象的类的类self.__class__.__class__;

__bases__,类的基类的元组,顺序为它们在基类列表中出现的顺序,不是mro;

__doc__,类、函数的文档字符串,如没定义为None;

__mro__,类的mro,class.mro()返回的结果保存在__mro__中,method resolution order,找链,mixin;

注:

single linkedlist中的__getitem__,仅用于容器,提供一种方便的接口,如索引或其它方式来用;

函数中的属性,foo.__defaults__,用元组保存位置参数默认值;

函数中的属性,foo.__kwdefaults__,用元组保存关键字参数默认值;

魔术方法分类:

创建与销毁:__init__、__del__;

hash;

bool;

__repr__、__str__,可视化;

__add__,运算符重载;

单(双)向链表中的[]、__getitem__、__sizeof__,容器和大小;

可调用对象,decorator、类装饰器;

上下文管理,with...as...;

反射(自省);

描述器;

其它杂项;

__dir__

查看属性,返回类或对象的所有成员名称列表;

dir()函数就是调用__dir__(),如果提供__dir__(),则返回属性的列表,否则会尽量从__dict__属性中收集信息;

如果dir(obj),参数obj中包含方法__dir__(),该方法将被调用,如果参数obj不包含__dir__(),该方法将大限度的收集参数信息;

dir(),对于不同类型的对象有不同的行为:

如果对象是模块对象,列表包含模块的属性名;

如果对象是类型或类对象,列表包含类的属性名、及它的基类的属性名;

否则,列表包含对象的属性名、它的类的属性名、类的基类的属性名;(向上逐级找)

例:

In [8]: dir()   #搜集当前模块

Out[8]:

['In',

'Out',

'_',

'_1',

'_2',

'_3',

'_4',

'_5',

'_7',

'__',

'___',

'__builtin__',

'__builtins__',

'__doc__',

'__loader__',

'__name__',

……

例:

class A:

def __init__(self,name=18):

self.name = name

class B(A):

def __dir__(self):   #实例的,类中的方法要看第1个参数,是self就是实例的

return ['abcdefg']   #必须返回列表,若写为return 'abcd'则返回['a','b','c','d']

b = B()

print(sorted(dir(b)))

print(sorted(dir(B)))

print(sorted(b.__dict__))

print(sorted(B.__dict__))

print(dir())   #pycharm中的dir(),__builtins__内置函数等,如果对象是模块对象,列表包含模块的属性名;

输出:

['abcdefg']

['__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']

['__dir__', '__doc__', '__module__']

['A', 'B', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'b']

例:

#example_class_magicmethod2.py

class Animal:

X = 123

def __init__(self,name):

self._name = name

self.__age = 10

self.weight = 20

print("animal module's name = {}".format(dir()))   #如果对象是模块对象,列表包含模块的属性名;

输出:

animal module's name = ['Animal', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

# example_class_magicmethod3.py

from example_class_magicmethod2 import Animal

import example_class_magicmethod2

class Cat(Animal):

X = 'cat'

Y = 'abcd'

class Dog(Animal):

def __dir__(self):

return ['dog']

print("current module's name = {}".format(dir()))   #模块名词空间内的属性

print("example_class_magicmethod2 module's name = {}".format(dir(example_class_magicmethod2)))   #指定模块名词空间内的属性

print('~~~~~~~~~~~~~~~~~~')

print("object's __dict__ = {}".format(object.__dict__.keys()))   #祖先类object的字典

print('~~~~~~~~~~~~~~~~~~')

print("Animal class's dir() = {}".format(dir(Animal)))   #类Animal的dir()

print("Cat class's dir() = {}".format(dir(Cat)))   #类Cat的dir()

print("Dog class's dir() = {}".format(dir(Dog)))

print('~~~~~~~~~~~~~~~~~~')

tom = Cat('tom')

print("Cat instance's dir() = {}".format(sorted(dir(tom))))   #实例的dir(),包括tom实例的属性、Cat类属性、祖先类object属性,sorted返回dict的key组成的列表

print("Cat instance's __dir__ = {}".format(sorted(tom.__dir__())))   #同上

print('~~~~~~~~~~~~~~~~~~')

print(sorted(set(tom.__dict__.keys()) | set(Cat.__dict__.keys()) | set(object.__dict__.keys())))   #实例的dir()近似等价于该行的__dict__所有(实例的、所属类的、祖先类的所有属性)属性;一般仅用__dict__就够了,是自己设计的,dir(tom)能查到所有;

print('~~~~~~~~~~~~~~~~~~')

print("Dog class's dir() = {}".format(dir(Dog)))

dog = Dog('snoopy')

print("Dog instance's dir() = {}".format(dir(dog)))

print("Dog instance's __dict__ = {}".format(dog.__dict__))

输出:

current module's name = ['Animal', 'Cat', 'Dog', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'example_class_magicmethod2']

example_class_magicmethod2 module's name = ['Animal', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

~~~~~~~~~~~~~~~~~~

object's __dict__ = dict_keys(['__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__', '__doc__'])

~~~~~~~~~~~~~~~~~~

Animal class's dir() = ['X', '__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__']

Cat class's dir() = ['X', 'Y', '__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__']

Dog class's dir() = ['X', '__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__']

~~~~~~~~~~~~~~~~~~

Cat instance's dir() = ['X', 'Y', '_Animal__age', '__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', 'weight']

Cat instance's __dir__ = ['X', 'Y', '_Animal__age', '__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', 'weight']

~~~~~~~~~~~~~~~~~~

['X', 'Y', '_Animal__age', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_name', 'weight']

~~~~~~~~~~~~~~~~~~

Dog class's dir() = ['X', '__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__']

Dog instance's dir() = ['dog']

Dog instance's __dict__ = {'_name': 'snoopy', '_Animal__age': 10, 'weight': 20}

例:

class A:

def __init__(self,name=18):

self.name = name

class B(A):

def __dir__(self):

return ['abcdefg']

b = B()

print('~~~~~~~~~~~~~')

print(sorted(dir(b)))

print(sorted(dir(B)))   #与dir(A)相等

print(sorted(dir(A)))

print('~~~~~~~~~~~~~')

print(sorted(b.__dict__))

print(sorted(A.__dict__))

print(sorted(B.__dict__))

print('~~~~~~~~~~~~~')

print(dir())

print(b.__dict__)

输出:

~~~~~~~~~~~~~

['abcdefg']

['__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__']

['__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']

['__dict__', '__doc__', '__init__', '__module__', '__weakref__']

['__dir__', '__doc__', '__module__']

~~~~~~~~~~~~~

['A', 'B', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'b']

{'name': 18}

__hash__

list源码中的;

@staticmethod   # known case of __new__ #很少用

def __new__(*args, **kwargs):    # real signature unknown

""" Create and return a new object.  See help(type) for accurate signature. """

Pass

__hash__ = None   #技巧,类中不可hashable写法,不可hash类型就是这样实现的

__hash__,内建函数hash()调用的返回值,只能返回一个整型(返回一个整数),如果定义这个方法,该类的实例就可hashable;

一切对象都有__hash__,来自object,object默认还实现了__eq__方法;

__eq__,对应==操作符,判断2个对象是否相等,返回bool值,若返回None则两个对象相等;

__hash__方法只是返回一个hash值作为set的key,但是去重还需要__eq__来判断2个对象是否相等;

哈希,时间复杂度O(1);

hash值相等,只是hash冲突,不能说明2个对象是相等的,因此,一般来说,提供__hash__方法是为了作为set或dict的key的,所以去重要同时提供这两个方法;

类中要两种同时用,__hash__、__eq__;

可hashable对象必须提供__hash__方法,没有提供的话,isinstance(p1,collections.Hashable)一定为False;

from collections import Hashable

print(Hashable(isinstance(A,Hashable)))   #很少用,可否hashable用hash()判断即可

注:

元组里有列表则不可hashable;

def __hash__(self),只能返回整型;

一致性hash,hash环,2^32;

def hash(x):

return x % 3   #return x % 3000000,冲突域大,则冲突可能性小

md5,单向散列,不可逆;

hash,一般在缓存中用,时间复杂度O(1);

缓冲,大坝,匹配生产者和消费者速度;

n个实例得到的hash值一样,hash冲突,dict要解决问题,解决办法:拉链法、开地址法;

__eq__,==,def __eq__(self,other): return None,则两个对象等效(相等);

例:

In [1]: o = [1,2,3]

In [2]: hash(o)  #相当于o.__hash__(),等价于None()

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

in ()

----> 1 hash(o)

TypeError: unhashable type: 'list'

In [3]: o.__hash__()

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

in ()

----> 1 o.__hash__()

TypeError: 'NoneType' object is not callable

例:

class A:

def __hash__(self):

return 1   #只能返回整型,否则TypeError: __hash__ method should return an integer

print(hash(A()))

输出:

1

例:

class A:

__hash__ = None   #不可hash类型就是这样实现的

print(hash(A()))

输出:

Traceback (most recent call last):

File "/home/python/magedu/projects/cmdb/example_class_magicmethod1.py", line 28, in

print(hash(A()))

TypeError: unhashable type: 'A'

例:

class A:

def __init__(self,name=18):

self.name = name

def __hash__(self):   #可hashable,hash冲突(hash值一样)

return 1

lst = [A(),A()]

print(lst)

s = set(lst)   #set还作了is判断

print(s)

print(len(s))   #2

for x in s:

print(hash(x))

输出:

[<__main__.A object at 0x7fee3d5f4438>, <__main__.A object at 0x7fee3d5f4b00>]

{<__main__.A object at 0x7fee3d5f4438>, <__main__.A object at 0x7fee3d5f4b00>}

2

1

1

例:

class A:

def __init__(self,name=18):

self.name = name

def __hash__(self):   #可hash

return 1

def __eq__(self, other):   #去重,两个是否相等,相等set才去重;可hash和去重是两个概念,两个一块用

# return False   #等价于上例,两个不相等,len(s)为2

# return True

return self.name == other.name

a = A(4)

b = A(4)

print(a.__dict__)

print(b.__dict__)

lst = [a,b]

print(lst)

s = set(lst)

print(s)

print(len(s))   #1

for x in s:

print(hash(x))

输出:

{'name': 4}

{'name': 4}

[<__main__.A object at 0x7f0a3e3ca438>, <__main__.A object at 0x7f0a3e3ca470>]

{<__main__.A object at 0x7f0a3e3ca438>}

1

1

例:

设计二维坐标类Point,比较2个坐标是否相等?

from collections import Hashable

class Point:

def __init__(self,x,y):

self.x = x

self.y = y

def __hash__(self):

return hash((self.x,self.y))

def __eq__(self, other):

return self.x == other.x and self.y == other.y

p1 = Point(4,5)

p2 = Point(4,5)

print(hash(p1))

print(hash(p2))

print(p1 is p2)   #False

print(p1 == p2)   #True

print(set((p1,p2)))

print(isinstance(p2,Hashable))   #True

输出:

3713084879518070856

3713084879518070856

False

True

{<__main__.Point object at 0x7fd0fc7e6b38>}

True

__bool__

内建函数bool(),或对象放在逻辑表达式的位置,调用这个函数返回布尔值;

没有定义__bool__(),就找__len__()返回长度,非0为真;如果__len__()也没有定义,那么所有实例都返回真;

__bool__()和__len__()都没有,恒为True;

empty list、empty set、empty tuple、empty dict,四大皆空,集合类型都为空,等效于False;

__bool__,调所有对象,逐级向上找,object中有__bool__的最简单实现,object上也没,就找__len__,__len__也没有,恒为True,一切皆为真;

有__len__,说明是个容器,里面没有东西说明为空,__len__返回值>=0;

注:

链表中不写__bool__,只写__len__,可实现等效False;

例:

class A:

pass

class B:

def __bool__(self):

# return False

return True

class C:

def __len__(self):

     # return 0

return 1

print(bool(A()))

print(bool(B))

print(bool(B()))

print(bool(C()))

print(C().__len__())

print(len(C()))

输出:

True

True

True

True

1

1

可视化

__repr__、__str__;

__repr__,内建函数repr()对一个对象获取字符串表达,如果一个类定义了__repr__()但有定义__str__,那么在请求该类的实例的“非正式”的字符串表示时也将调用__repr__();

__str__,str()函数,内建函数format、print()调用,需要返回对象的字符串表达;

__bytes__,bytes的时候,返回一个对象的bytes表达,即返回bytes对象;

__repr__、__str__都没有,找object(打印内存地址);

没有__str__,找__repr__;

没有__repr__,只有__str__:

str()、format、print使用没问题;

内部打印找object,如print([A()]),显示[<__main__.A object at 0x7f5ac6059470>];

一般__repr__、__str__两个都要,写的一模一样;

技巧,在定义__repr__后,__str__ =  __repr__,类似__hash__ = None;

例:

class A:

def __init__(self):

self.a = 'a'

self.b = 'b'

def __repr__(self):

return 'repr: {},{}'.format(self.a,self.b)

def __str__(self):

return 'str: {},{}'.format(self.a,self.b)

print(A())   #print函数使用__str__

print([A()])   #[]使用__str__,但其内部使用__repr__

print(([str(A())]))   #[]使用__str__,str()函数也使用__str__

print('str:a,b')

s = 'b'

print(['a'],(s,))

输出:

str: a,b

[repr: a,b]

['str: a,b']

str:a,b

['a'] ('b',)

例2:

class A:

def __init__(self):

self.a = 'a'

self.b = 'b'

# def __repr__(self):

#     return 'repr: {},{}'.format(self.a,self.b)

def __str__(self):

return 'str: {},{}'.format(self.a,self.b)

print(A())

print([A()])   #内部调用__repr__(),__repr__()没有则调用object打印内存地址

print(([str(A())]))

print('str:a,b')

s = 'b'

print(['a'],(s,))

输出:

str: a,b

[<__main__.A object at 0x7f5ac6059470>]

['str: a,b']

str:a,b

['a'] ('b',)

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


新闻标题:29面向对象4_dir-hash-bool-repr-str-创新互联
网页URL:http://kswsj.cn/article/cojdop.html

其他资讯