Python- 魔法方法【实例化、可视化、bool、运算符重载】

1、实例化【__new__】

1.1、方法介绍

方法                意义
__new__             实例化一个对象
                    该方法需要返回一个值,如果该值不是cls的实例,则不会调用 __init__该方法永远都是静态方法

1.2、示例

class A:
    def __new__(cls, *args, **kwargs):
        print(cls)
        print(args)
        print(kwargs)
        # return super().__new__(cls) # 调用__init__方法,初始化对象
        return 1
        # return None
    def __init__(self, name):
        self.name = name
a = A()
print(a)

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

2、可视化【__str__、__repr__、__bytes__】

2.1、方法介绍

方法            意义
__str__         str()函数、format()函数、print()函数调用,需要返回对象的字符串表达。如果没有定义,就去调用 __repr__ 方法返回字符串表达,如果 __repr__ 没有定义,就直接返回对象的内存地址信息
__repr__        内建函数repr()对一个对象获取字符串表达。调用 __repr__ 方法返回字符串表达,如果 __repr__ 也没有定义,就直接返回object的定义就是显示内存地址信息
__bytes__       bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象

2.2、示例

class A:
    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):
        #return "{} is {}".format(self.name, self.age).encode()
        import json
        return json.dumps(self.__dict__).encode()

print(A('tom')) # print函数使用__str__
print('{}'.format(A('tom')))
print([A('tom')]) # []使用__str__,但其内部使用__repr__
print([str(A('tom'))]) # []使用__str__,其中的元素使用str()函数也调用__str__
print(bytes(A('tom')))

# str: tom,18
# str: tom,18
# [repr: tom,18]
# ['str: tom,18']
# b'{"name": "tom", "age": 18}'

3、bool【__bool__】

3.1、方法介绍

方法        意义
__bool__   内建函数bool(),或者对象放在逻辑表达式的位置,调用这个函数返回布尔值。没有定义 __bool__ (),就找 __len__ ()返回长度,非0为真。
如果 __len__ ()也没有定义,那么所有实例都返回真

3.2、示例

class A: pass
a = A()
print(bool(A))
print(bool(a))

class B:
    def __bool__(self):
        return False
print(bool(B))
print(bool(B()))

if B():
    print('Real B instance')

class C:
    def __len__(self):
        return 0

print(bool(C))
print(bool(C()))

if C():
    print('Real C instance')

4、运算符重载

4.1、方法介绍

operator模块提供以下的特殊方法,可以将类的实例使用下面的操作符来操作
比较运算符:
<, <=, ==, >,
>=, !=

__lt__ , __le__ , __eq__ , __gt__ , __ge__ ,
__ne__


算数运算符,移位、位运算也有对应的方法:
+, -, *, /, %,
//, **,divmod

__add__ , __sub__ , __mul__ , __truediv__ ,
__mod__ , __floordiv__ , __pow__ , __divmod__


+=, -=, *=,
/=, %=, //=,
**=
__iadd__ , __isub__ , __imul__ , __itruediv__ ,
__imod__ , __ifloordiv__ , __ipow__

4.2、示例:实现自定义类的实例的大小比较(非常重要,排序时使用)

class A:
    pass
print(A() == A()) # False
print(A() > A()) # TypeError: '>' not supported between instances of 'A' and 'A'
class A:
    def __init__(self, name, age=18):
        self.name = name
        self.age = age

    def __eq__(self, other):
        return self.name == other.name and self.age == other.age

    def __gt__(self, other):
        return self.age > other.age

    def __ge__(self, other):
        return self.age >= other.age


tom = A('tom')
jerry = A('jerry', 16)
print(tom == jerry, tom != jerry)  # False True
print(tom > jerry, tom < jerry)  # True False
print(tom >= jerry, tom <= jerry)  # True False

# __eq__ 等于可以推断不等于
# __gt__ 大于可以推断小于
# __ge__ 大于等于可以推断小于等于
# 也就是用3个方法,就可以把所有比较解决了

4.3、示例:实现两个学生的成绩差

4.3.1、原始方法

class A:
    def __init__(self, name, score):
        self.name = name
        self.score = score

tom = A('tom', 80)
jerry = A('jerry', 85)
print(tom.score - jerry.score)

4.3.2、__sub__方法

class A:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def __sub__(self, other):
        return self.score - other.score


tom = A('tom', 80)
jerry = A('jerry', 85)
print(tom.score - jerry.score)  # -5
print(tom - jerry)  # -5
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~')
jerry -= tom  # 调用sub
print(tom)
print(jerry)  # 5

4.3.3、__sub__、__isub__方法

class A:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def __sub__(self, other):
        return self.score - other.score

    def __isub__(self, other):
        # return A(self.name, self.score - other.score)
        self.score -= other.score
        return self

    def __repr__(self):
        return "<A name={}, score={}>".format(self.name, self.score)


tom = A('tom', 80)
jerry = A('jerry', 85)
print(tom.score - jerry.score)  # -5
print(tom - jerry)  # -5
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~')
jerry -= tom  # 调用isub
print(tom)  # <A name=tom, score=80>
print(jerry)  # <A name=jerry, score=5>

 

posted @ 2023-07-19 10:04  小粉优化大师  阅读(63)  评论(0)    收藏  举报