注册 登录
Python基础教程

第一章: 环境搭建,安装Python

第二章: 挑选一款趁手的IDE

第三章: 计算机基础知识

第四章: 命令行基础知识

第五章: 从全局把握Python

第六章: Python语言基础

第七章: Python流程控制

第八章: Python数据类型与运算

第九章: Python字符串类型

第十章: Python列表类型

第十一章: Python元组类型

第十二章: Python字典类型

第十三章: Python集合类型

第十四章: Python函数处理

第十五章: Python文件处理

第十六章: Python面向对象

第十七章: Python异常处理

第十八章: Python模块处理

第十九章: Python高级编程

第二十章: Python项目实战

首页 > Python基础教程 > 第十六章: Python面向对象 > 16.6节: 魔术属性与魔术方法

16.6节: 魔术属性与魔术方法

薯条老师 2022-11-25 12:22:50 27369 0

编辑 收藏

广州番禺Python, Java小班周末班培训

薯条老师在广州做Python和Java的小班培训,一个班最多10人,学员的平均就业薪资有11K。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。培训的课程有Python爬虫,Python后端开发,Python办公自动化,Python大数据分析,Python量化投资,Python机器学习,Java中高级后端开发。授课详情请点击:http://chipscoco.com/?cate=6

16.6.1 内置的dir方法

Python提供了一个内置函数dir,在dir函数中传递类型名或对象名,可以查看数据类型或对象中的属性和方法。dir的输出是一个列表,列表中包含的元素是数据类型中的属性和方法。现在进入Python交互模式,执行dir(dict)来查看字典中的所有属性和方法:
>>> dir(dict)
['__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']

在dir的输出中,我们可以看到前后带有双下划线__的属性或方法。在Python中前后带有双下划线的属性统称为魔术属性,前后带有双下划线的方法统称为魔术方法。

16.6.2 常用的魔术属性

Python中常用的魔术属性主要有:__class__,__dict__,__doc__。

(1) __class__
返回实例对象的数据类型,同学们要注意的是__class__返回的是类类型。

代码实例:

# 定义一个Cat类
class Cat:
    def __init__(self, name):
        self.__name = name
 
kitty = Cat("kitty")
print(kitty.__class__)
 
"""
(1) 执行print后的输出:
<class '__main__.Cat'>
(2) __class__的输出是一个类类型,所以可以通过__class__来进行对象的实例化
例如:lisa = kitty.__class__("lisa")
"""
(2) __dict__:
对于类类型来说,__dict__保存的是类的属性与方法,对于实例对象来说,__dict__保存的是实例对象的属性。

代码实例:

# __desc__ = 测试魔法属性__dict__
 
class Cat:
    # 定义类属性species,来表示猫所属的物种
    __species = "Cat" 
 
    @classmethod
    def catch_mice(cls):
        print("A cat that doesn't catch a mouse is not a good cat!")
 
    def __init__(self,name):
        # 在对象属性前面加上双下划线
        self.__name = name
 
    def miaow(self):
        # 在类内部可以访问被"隐藏"的属性和方法
        print("{} miaow when unhappy".format(self.__name))
 

 # 访问类型中的__dict__
print(Cat.__dict__)
"""
输出为:
{'__module__': '__main__', '_Cat__species': 'Cat', 'catch_mice': <classmethod object at 0x0000017C5EB6EE88>, '__init__': <function Cat.__init__ at 0x0000017C5EAFD5E8>, 'miaow': <function Cat.miaow at 0x0000017C5EAFD678>, '__dict__': <attribute '__dict__' of 'Cat' objects>, '__weakref__': <attribute '__weakref__' of 'Cat' objects>, '__doc__': None}
"""
 
 
# 访问对象中的__dict__
kitty = Cat("kitty")
print(kitty.__dict__)

"""
输出为:
{'_Cat__name': 'kitty'}
 
"""
(2) __doc__

__doc__表示文档字符串,文档字符串是一段是用三引号括住的字符串,出现在类体或函数体中的第一行,用来对类或函数进行功能及用法上的描述。
Python中的第三方工具会将文档字符串自动生成一个描述性的文档。

代码实例:

# 定义一个Cat类
class Cat:
    def __init__(self, name):
        """ this cat is not a real cat,no rat """
        self.__name = name
 
print(Cat.__doc__)
 
# 程序的输出为:this cat is not a real cat,no rat

16.6.3 常用的魔术方法

类中的魔术方法会自动被Python调用,例如在进行对象的实例化时,会自动调用构造函数__init__。现在开始来讲解Python中的常用的魔术方法。

(1) __str__
输出实例对象时会自动调用该方法,该方法用于输出实例对象的内存地址,返回值必须为字符串类型。

代码实例:

# __desc__ = 重定义__str__方法
 
class Cat:
    # 定义类属性species,来表示猫所属的物种
    __species = "Cat" 
 
    def __init__(self,name):
        # 在对象属性前面加上双下划线
        self.__name = name
 
 
cat = Cat("kitty")
print(cat)
 
"""
未定义__str__方法时,输出的是对象的内存地址 
<__main__.Cat object at 0x03738210>
"""
 
# 重定义__str__方法,修改对象的输出信息
class Cat:
    # 定义类属性species,来表示猫所属的物种
    __species = "Cat" 
 
    def __init__(self,name):
        # 在对象属性前面加上双下划线
        self.__name = name
 
    def __str__(self):
        # 该方法返回的是字符串类型
        return "this cat is not a real cat,no rat"
 
cat = Cat("kitty")
print(cat)
 
"""
通过print来输出对象,Python会自动调用__str__方法
程序的输出为:
"this cat is not a real cat,no rat"
"""
(2) __call__
对__call__方法进行重定义,使得实例化后的对象可以像函数一样调用。

代码实例:

# __desc__ = 重定义__call__方法
 
class Cat:
    # 定义类属性species,来表示猫所属的物种
    __species = "Cat" 
 
    def __init__(self,name):
        # 在对象属性前面加上双下划线
        self.__name = name
 
    def __call__(self):
        return "this cat is not a real cat,no rat"
 
 
cat = Cat("kitty")
print(cat())
 
"""
(1)以函数调用的形式来调用对象
(2)Python会自动调用__call__方法,程序的输出为:
"this cat is not a real cat,no rat"
"""
(3) __getattr__(self,name)
参数name表示属性名,访问不存在的属性时,会触发该方法的调用。通过__getattr__方法可以实现属性的惰性初始化,所谓的惰性初始化,即仅在需要的时候才定义相关属性。
惰性初始化有时会很有用,比如某些属性的初始化时间很长或占用较多的系统资源,那么仅在需要的时候才定义该属性,可以加快对象的构造以及节约系统资源。
代码实例:
# __desc__ = 通过__getattr__方法来实现惰性初始化
 
class Cat:
    __species = "Cat" 
 
    def __init__(self, name):
        self.__name = name
        # 定义对象中的惰性属性名,键值为简单的lambda函数,用来模拟耗时的初始化
        self.__lazy_attribute = {
        "cry":lambda x:x*x
        }
 
 
    def __lazy_initialize(self, name):
        return self.__lazy_attribute[name](0)
 
 
    def __getattr__(self, name):
        # 如果该属性为惰性属性,且还未初始化,那么现在进行初始化
        if name in self.__lazy_attribute:
            # __dict__保存了对象的属性,这样就相当于定义了name参数对应的属性
            self.__dict__[name] = self.__lazy_initialize(name)
            return self.__dict__[name]
 
        return None
 
kitty = Cat("kitty")
# 访问不存在的cry属性,会执行__getattr__方法
print(kitty.cry)
# 程序的输出为0
在对属性进行设置时,会执行__setattr__的方法。同学们需避免在__setattr_函数内为属性赋值,否则会触发递归调用。
(4) __getitem__(self, key):
在类中定义该方法可以通过操作符[]的形式来对对象属性进行访问。参数key表示属性名或索引值。
# __desc__ = 定义__getitem__的方法,以操作符[]的形式对对象属性进行访问
 
class Cat:
    __species = "Cat" 
 
    def __init__(self, name):
        self.name = name
 
    def __getitem__(self, name):
        if name in self.__dict__:
            # 如果为对象属性,就输出属性的值
            return self.__dict__[name] 
 
        return None
 

cat = Cat("kitty")
"""
定义__getitem__方法以后,可以按照字典的方式来访问对象属性
"""
print(cat["name"])
# 程序的输出为:kitty
定义__getitem__方法可以让当前类型实现迭代功能,可以使用for循环结构来对元素进行遍历,Python会自动传递编号为0的索引,并不断更新索引的值。
代码实例:
# __desc__ = 通过__getitem__方法来实现迭代
 
class Cat:
    __species = "Cat" 
    __cats = ["tiger", "lion"]
 
    def __init__(self, name):
        self.name = name
 
    def __getitem__(self, index):
        return self.__cats[index]
 
 
cats = Cat("kitty")
for cat in cats:
    print(cat)
 
"""
程序的输出为:
tiger
lion
"""
(5) __setitem__(self, key, value):
在类中定义该方法可以通过操作符[]的形式来对对象属性进行赋值。key值的使用以及不正确的 key 值所引发的异常与 __getitem__() 方法的情况相同。
代码实例:
# __desc__ = 通过__setitem__方法来实现[]操作
 
class Cat:
    __species = "Cat" 
 
    def __init__(self, name):
        self.name = name
 
    def __setitem__(self, name, value):
        self.__dict__[name] = value
 
kitty = Cat("kitty")
 
# 以[]的形式为属性赋值时会触发__setitem__方法的调用
kitty["price"] = 69
 
print(kitty.price)
# 程序的输出为:69

16.6.4 最具实力的小班培训

薯条老师在广州做Python和Java的小班培训,一个班最多10人。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习打算参加小班培训的同学,必须遵守薯条老师的学习安排,认真做作业和项目。把知识学好,学扎实,那么找到一份高薪的工作就是很简单的一件事。

(1) Python后端工程师高薪就业班,月薪11K-18K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪11K-20K, 免费领取课程大纲
(4) Python大数据分析,量化投资就业班,月薪12K-25K,免费领取课程大纲

扫码免费领取Python学习资料:

关注微信公众号.jpg













欢迎 发表评论:

请登录

忘记密码我要注册

注册账号

已有账号?请登录