首页 > 编程语言 > 详细

python学习笔记17

时间:2020-04-03 21:13:34      阅读:65      评论:0      收藏:0      [点我收藏+]

python学习笔记17

两个装饰器

@classmethod

被修饰的方法成为一个类方法。

什么时候用@classmethod:1. 类内部定义了一个方法,默认传入self,但是self并没有被使用;2. 在这个方法中用到了当前的类名,或者准备使用这个类的内存空间中的名字

class Cir:
    __pi = 3.14
    def __init__(self,r):
        self.r = r
        self.area = __pi*self.r**2
    # 正常我们对这么定义一个内部方法:
    # def change_pi(self,new_pi):
    #     Cir.__pi = new_pi # 这里不能使用self.__pi,因为这样会创建一个新的私有变量
    @classmethod # 把一个对象绑定的方法修改成一个类方法
    def change_pi(cls,new_pi):
        cls.__pi = new_pi # 这里相当于Cir.__pi = new_pi

使用@classmethod的好处:1. 在方法中仍然可以引用类中的静态变量;2. 可以不用实例化对象,直接用类名在外部调用这个方法。

@staticmethod

被修饰的方法成为一个静态方法。

# 当在类的内部定义一个不带self参数的普通函数时加上@staticmethod修饰器
class A:
    def func():
        print(666)
# 尝试执行func函数
A().func() # TypeError: func() takes 0 positional arguments but 1 was given
# 函数报错,因为类中的方法会默认传入self
# 所以需要加上@staticmethod
class A:
    @staticmethod
    def func():
        print(666)
# 再次执行
A().func() # 666
# 加上这个修饰器后的函数内部既不会用到self变量也不会用到cls类

一些内置的魔术方法

__new__

构造方法:创建一个实例化对象时,总是先创建一块对象的空间,有一个指针能指向类。这就是__new__方法完成的工作。

class A:
    def __new__(cls,*args,**kwargs):
        ans = super().__new__(cls)
        print(‘执行new‘,ans)
        return ans
    def __init__(self):
        print(‘执行init‘,self)
# 观察创建一个实例化对象后的输出
A()
"""
执行new <__main__.A object at 0x0000021BF45F61C8>
执行init <__main__.A object at 0x0000021BF45F61C8>
"""
# 可以看到两个结果的地址完全相同
# 其实在实例化一个对象的时候,总是先执行__new__方法开辟空间
# 再执行__init__方法

__call__

带有__call__方法 的类是可调用的(callable)。

# 当类中没有__call__方法时
class A:
    pass
print(callable(A())) # False
# 当类中有__call__方法时
class B:
    def __call__(self):
        print(666)
print(callable(B())) # True
# 对象名+()默认调用类中的__call__方法
# 创建一个类的实例化对象
obj = B()
obj() # 666

__len__

对对象求长度时调用的方法。

class A:
    def __init__(self):
        self.li_1 = []
obj = A()
# 向列表添加元素
obj.li_1.append(1)
obj.li_1.append(2)
print(len(obj.li_1)) # 2
obj.li_1.append(3)
obj.li_1.append(4)
print(len(obj.li_1)) # 4
# 当向类中加入__len__方法后
class A:
    def __init__(self):
        self.li_1 = []
    def __len__(self):
        return len(self.li_1)
obj = A()
# 可以直接对对象求长度获得属性长度
obj.li_1.append(1)
obj.li_1.append(2)
print(len(obj)) # 2
obj.li_1.append(3)
obj.li_1.append(4)
print(len(obj)) # 4

__str__

当打印实例化对象时,如果类内部没有__str__方法就输出对象所在的内存地址,有__str__方法时直接输出__str__方法return的结果(但是这个方法只能返回str类型的结果)。

# 当不定义__str__方法时
class People:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __str__(self):
        return ‘,‘.join([self.name,str(self.age),self.sex])
xiaoming = People(‘xiaoming‘,22,‘male‘)
xiaohong = People(‘xiaohong‘,21,‘female‘)
xiaohei = People(‘xiaohei‘,22,‘male‘)
print(xiaoming) # <__main__.People object at 0x0000021BF454D908>
# 输出结果是一个地址,内容不够直观
# 定义__str__方法后
class People:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __str__(self):
        return ‘,‘.join([self.name,str(self.age),self.sex])
xiaoming = People(‘xiaoming‘,22,‘male‘)
xiaohong = People(‘xiaohong‘,21,‘female‘)
xiaohei = People(‘xiaohei‘,22,‘male‘)
print(xiaoming) # xiaoming,22,male
# 直接输出结果,清晰明了

__repr__

print一个对象,用%s进行字符串拼接或者str(对象)时总是调用这个对象的__str__方法,如果找不到__str__方法则调用__repr__方法;用%r进行字符串拼接或者str(对象)时总是调用这个对象的__repr__方法。

python学习笔记17

原文:https://www.cnblogs.com/20-03-14/p/12628916.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!