Python魔术方法Magic Methods ( 十一)

本文深入探讨Python中的魔术方法,包括实例化过程、可视化的魔术方法如hash和bool,以及运算符重载。接着讨论了容器相关的方法和上下文管理,介绍了反射的概念及相关函数,如getattr、setattr等。最后,详细阐述了描述器的原理和应用,通过案例展示了如何实现静态方法和类方法装饰器。
摘要由CSDN通过智能技术生成

​ 实例化

一.实例化一个对象

  __new__:
    该方法需要返回一个值,如果该值不是cls的实例,则不会调用"__init__"。该方法永远都是静态方法。
#!/usr/bin/env python
#_*_conding:utf-8_*_


class Person:
    def __new__(cls, *args, **kwargs):
        print(cls)
        print(args)
        print(kwargs)
        # return super().__new__(cls)
        return 2019

    def __init__(self,name):
        self.name = name

print("{0} 我是分割线 {0}".format("*" * 20))
p1 = Person("Jason Yin")

print("{0} 我是分割线 {0}".format("*" * 20))
print(p1)



#以上代码执行结果如下:
******************** 我是分割线 ********************
<class '__main__.Person'>
('Jason Yin',)
{}
******************** 我是分割线 ********************
2019

三.总结

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

​ 可视化

一.关于可视化的魔术方法简介

  __str__:
    str()函数,format()函数,print()函数调用,需要返回对象的字符串表达式,即会默认调用该魔术方法。
    如果没有定义该方法,就去调用"__repr__"方法返回字符串表达式,如果"__repr__"没有定义,就直接返回对象的内存地址信息。

  __repr__:
    内建函数repr()对一个对象获取字符串表达。
    调用"__repr__"方法返回字符串表达,如果"__repr__"也没有定义,就直接返回object的定义就是显示内存地址信息。

  __bytes__:
    bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象。
#!/usr/bin/env python
#_*_conding:utf-8_*_


class Person:
    def __init__(self,name,age=18):
        self.name = name
        self.age = age

    def __repr__(self):
        return "repr:{},{}".format(self.name,self.age)

    def __str__(self):
        return "str:{},{}".format(self.name,self.age)

    def __bytes__(self):
        import json
        return json.dumps(self.__dict__).encode()

p1 = Person("Jason Yin")

print(p1)                   #print函数默认调用的是str方法

print("{}".format(p1))      #字符串的format方法也是调用"__str__"方法

print([p1])                 #使用引用类型存储p1时,发现调用的时"__repr__"方法

print([str(p1)])            #我们可以显示使用str函数去调用"__str__"魔术方法,如果没有"__str__"方法就去找"__repr__"方法

print(bytes(p1))            #调用的是"__bytes__"方法

"""
    温馨提示:
        在学习完可视化方法后,同学们应该明白之前我们看到所有的字符串输出其实都是别人封装好的魔术方法,比如:print(1,'1',['1',1])
        因此,咱们不能通过判断是否带引号来判断输出值的类型,类型判断需要使用type或者isinstance.
"""



#以上代码执行结果如下:
str:Jason Yin,18
str:Jason Yin,18
[repr:Jason Yin,18]
['str:Jason Yin,18']
b'{"name": "Jason Yin", "age": 18}'

一.hash方法

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

__eq__:
  对应"=="操作符,判断两个对象内容是否相等,返回bool值。
  定义了这个方法,如果不提供"__hash__"方法,那么实例将不可hash了。
  "__hash__"方法只是返回一个hash值作为set的key,但是去重还需要"__eq__"来判断两个对象是否相等。
  hash值相同,只是hash冲突,不能说明两个对象是相等的。因此一半来说提供"__hash__"方法是为了作为set或者dict的key,如果去重同时要提供"__eq__"方法。
 
温馨提示:
  不可hash对象isinstance(p1,collections.Hashable)一定为False。
  去重需要提供"__eq__"方法。
#!/usr/bin/env python
#_*_conding:utf-8_*_


"""
    设计二维坐标类Point,使其成为可hash类型,并比较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):
        if self is other:
            return True
        else:
            return self.x == other.x and self.y == other.y

    def __repr__(self):
        return "{}:{}".format(self.x,self.y)

p1 = Point(10,20)
p2 = Point(10,20)

print(hash(p1))
print(hash(p2))

print(p1 is p2)
print(p1 == p2)
print(hex(id(p1)),hex(id(p2)))
print(set((p1,p2)))
print(isinstance(p1,Hashable))



#以上代码执行结果如下:
3713074054217192181
3713074054217192181
False
True
0x137152b7888 0x137152b9348
{10:20}
True

三.小时牛刀

1>.list类实例为什么不可hash?

1 class list(object):
  2     """
  3     Built-in mutable sequence.
  4     
  5     If no argument is given, the constructor creates a new empty list.
  6     The argument must be an iterable if specified.
  7     """
  8     def append(self, *args, **kwargs): # real signature unknown
  9         """ Append object to the end of the list. """
 10         pass
 11 
 12     def clear(self, *args, **kwargs): # real signature unknown
 13         """ Remove all items from list. """
 14         pass
 15 
 16     def copy(self, *args, **kwargs): # real signature unknown
 17         """ Return a shallow copy of the list. """
 18         pass
 19 
 20     def count(self, *args, **kwargs): # real signature unknown
 21         """ Return number of occurrences of value. """
 22         pass
 23 
 24     def extend(self, *args, **kwargs): # real signature unknown
 25         """ Extend list by appending elements from the iterable. """
 26         pass
 27 
 28     def index(self, *args, **kwargs): # real signature unknown
 29         """
 30         Return first index of value.
 31         
 32         Raises ValueError if the value is not present.
 33         """
 34         pass
 35 
 36     def insert(self, *args, **kwargs): # real signature unknown
 37         """ Insert object before index. """
 38         pass
 39 
 40     def pop(self, *args, **kwargs): # real signature unknown
 41         """
 42         Remove and return item at index (default last).
 43         
 44         Raises IndexError if list is empty or index is out of range.
 45         """
 46         pass
 47 
 48     def remove(self, *args, **kwargs): # real signature unknown
 49         """
 50         Remove first occurrence of value.
 51         
 52         Raises ValueError if the value is not present.
 53         """
 54         pass
 55 
 56     def reverse(self, *args, **kwargs): # real signature unknown
 57         """ Reverse *IN PLACE*. """
 58         pass
 59 
 60     def sort(self, *args, **kwargs): # real signature unknown
 61         """ Stable sort *IN PLACE*. """
 62         pass
 63 
 64     def __add__(self, *args, **kwargs): # real signature unknown
 65         """ Return self+value. """
 66         pass
 67 
 68     def __contains__(self, *args, **kwargs): # real signature unknown
 69         """ Return key in self. """
 70         pass
 71 
 72     def __delitem__(self, *args, **kwargs): # real signature unknown
 73         """ Delete self[key]. """
 74         pass
 75 
 76     def __eq__(self, *args, **kwargs): # real signature unknown
 77         """ Return self==value. """
 78         pass
 79 
 80     def __getattribute__(self, *args, **kwargs): # real signature unknown
 81         """ Return getattr(self, name). """
 82         pass
 83 
 84     def __getitem__(self, y): # real signature unknown; restored from __doc__
 85         """ x.__getitem__(y) <==> x[y] """
 86         pass
 87 
 88     def __ge__(self, *args, **kwargs): # real signature unknown
 89         """ Return self>=value. """
 90         pass
 91 
 92     def __gt__(self, *args, **kwargs): # real signature unknown
 93         """ Return self>value. """
 94         pass
 95 
 96     def __iadd__(self, *args, **kwargs): # real signature unknown
 97         """ Implement self+=value. """
 98         pass
 99 
100     def __imul__(self, *args, **kwargs): # real signature unknown
101         """ Implement self*=value. """
102         pass
103 
104     def __init__(self, seq=()): # known special case of list.__init__
105         """
106         Built-in mutable sequence.
107         
108         If no argument is given, the constructor creates a new empty list.
109         The argument must be an iterable if specified.
110         # (copied from class doc)
111         """
112         pass
113 
114     def __iter__(self, *args, **kwargs): # real signature unknown
115         """ Implement iter(self). """
116         pass
117 
118     def __len__(self, *args, **kwargs): # real signature unknown
119         """ Return len(self). """
120         pass
121 
122     def __le__(self, *args, **kwargs): # real signature unknown
123         """ Return self<=value. """
124         pass
125 
126     def __lt__(self, *args, **kwargs): # real signature unknown
127         """ Return self<value. """
128         pass
129 
130     def __mul__(self, *args, **kwargs): # real signature unknown
131         """ Return self*value. """
132         pass
133 
134     @staticmethod # known case of __new__
135     def __new__(*args, **kwargs): # real signature unknown
136         """ Create and return a new object.  See help(type) for accurate signature. """
137         pass
138 
139     def __ne__(self, *args, **kwargs): # real signature unknown
140         """ Return self!=value. """
141         pass
142 
143     def __repr__(self, *args, **kwargs): # real signature unknown
144         """ Return repr(self). """
145         pass
146 
147     def __reversed__(self, *args, **kwargs): # real signature unknown
148         """ Return a reverse iterator over the list. """
149         pass
150 
151     def __rmul__(self, *args, **kwargs): # real signature unknown
152         """ Return value*self. """
153         pass
154 
155     def __setitem__(self, *args, **kwargs): # re
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值