Python对象属性操作详解:探讨内置函数getattr、setattr、delattr、hasattr与vars的使用与功能

目录

  • 一、功能
  • 二、语法和示例
  • 三、其他常用属性操作相关的内置函数
  • 3.1 setattr()函数——设置对象的属性值
  • 3.2 delattr()函数——删除对象的属性
  • 3.3 hasattr()函数——检查对象是否含有属性
  • 3.4 vars()函数——获取对象的属性和属性值
  • 一、功能

    getattr()函数——获取对象的属性值

    二、语法和示例

    getattr() 函数的语法格式如下:

    getattr(object, name[, default])
    参数说明:
    1.object: 对象
    2.name: 字符串,对象属性
    3.default: 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError
    4.返回值: 返回对象属性
    

    【示例1】使用getattr()函数获取实例对象属性值,代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:34
    # @Author  : AmoXiang
    # @File    : getattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student(object):
        name = 'Andy'
        age = 18
    
        def hello(self):
            return 'hello'
    
    
    s = Student()
    print(getattr(Student, 'name'))
    f = getattr(s, 'hello')
    print(getattr(s, 'name'))
    print(getattr(s, 'age'))
    print(getattr(s, 'gender', '男'))
    print(f())
    

    【示例2】使用try-except 语句捕获getattr()函数获取属性失败时的异常,代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:34
    # @Author  : AmoXiang
    # @File    : getattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
    
    s = Student()  # 实例化Student类
    
    # 捕获属性异常
    try:
        print(getattr(s, 'gender'))
    except AttributeError:
        print('没有该属性')
    

    【示例3】使用多种方式打开文件。创建一个类,根据接受到的参数,以不同的方式打开文件。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:34
    # @Author  : AmoXiang
    # @File    : getattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Dbf(object):
    
        def __init__(self, f, read_only=False, new=False):
            if isinstance(f, str):
                # 如果是文件
                self.name = f
                if new:
                    # 如果new参数为真,以写入二进制方式打开
                    self.stream = open(f, "w+b")
                else:
                    # 否则,以二进制读的方式打开
                    self.stream = open(f, ("r+b", "rb")[bool(read_only)])
    
            else:
                # 如果是数据流
                self.name = getattr(f, "name", "")  # 获取stream的name属性,赋值给实例属性
                self.stream = f  # 将stream赋值给实例属性
    
    
    dbf = Dbf('hello.txt')  # 传递文件名
    print(dbf.stream)
    stream = open('hello.txt', 'r+b')  # 打开文件
    new_dbf = Dbf(stream)  # 传递stream数据流
    print(new_dbf.stream)
    print('文件名是{}'.format(new_dbf.name))
    

    【示例4】实现“授权”的功能。所谓授权,是指包装一个数据类型,通常是对已存在的类型的一些定制。这种做法可以新建、修改或删除原有产品的功能,其他属性则保持原样。授权的过程,即是所有新增的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。实现授权的关键点就是覆盖 __getattr__()方法。下面实现对一个文件句柄类型进行“授权”。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:34
    # @Author  : AmoXiang
    # @File    : getattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    import time
    
    
    class FileHandle:
        """ '授权' 类 """
    
        def __init__(self, filename, mode='r', encoding='utf-8'):
            # 对一个文件句柄进行"授权"
            self.file = open(filename, mode, encoding=encoding)
    
        def write(self, line):  # 新增的功能
            t = time.strftime('%Y-%m-%d %T')
            self.file.write('%s %s' % (t, line))
    
        def __getattr__(self, item):  # 保留原有的功能
            return getattr(self.file, item)
    
    
    f1 = FileHandle('test.txt', 'w+')  # 创建"授权"类对象
    f1.write('Hello 5.1节!')  # 写入数据
    f1.seek(0)  # 定位光标
    print(f1.read())  # 读取数据
    f1.close()  # 关闭文件句柄
    

    【示例5】在实现“授权”功能的基础之上,对文件句柄类型添加 'b' 模式的支持。从此再在写入数据时,不管是对于字符串还是字节数据,都直接可以写入,不需再去关注数据写入的数据格式。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:34
    # @Author  : AmoXiang
    # @File    : getattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class FileHandle:
        def __init__(self, filename, mode='r', encoding='utf-8'):
            if 'b' in mode:
                self.file = open(filename, mode)  # 'b'模式不加编码方式
            else:
                self.file = open(filename, mode, encoding=encoding)
            self.filename = filename
            self.mode = mode
            self.encoding = encoding
    
        def write(self, line):
            if 'b' in self.mode:
                if not isinstance(line, bytes):  # 添加类型检查
                    self.file.write(line.encode(self.encoding))
                else:
                    self.file.write(line)
    
        def __getattr__(self, item):  # 新增的功能
            return getattr(self.file, item)
    
        def __str__(self):
            if 'b' in self.mode:
                res = "<_io.BufferedReader name='%s'>" % self.filename
            else:
                res = "<_io.TextIOWrapper name='%s' mode='%s' encoding='%s'>" % \
                      (self.filename, self.mode, self.encoding)
            return res
    
    
    f1 = FileHandle('test2.txt', 'wb')
    # 自定制的 write()方法, 不需再手动进行encode, 使用更加方便。
    f1.write('你好啊 2025-05-01!')
    f1.write(' Amo老师 ')
    print(f1)
    f1.close()  # 关闭文件句柄,释放资源
    

    三、其他常用属性操作相关的内置函数

    3.1 setattr()函数——设置对象的属性值

    setattr 函数的语法格式如下:

    参数说明:

    1. object:对象
    2. name:字符串,对象属性
    3. value:属性值
    4. 返回值:无

    【示例1】使用setattr()函数替换实例中已经存在的属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:11
    # @Author  : AmoXiang
    # @File    : setattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
    
        age = 18
    
    
    s = Student()
    print(getattr(s, 'name'))  # Andy
    setattr(s, 'name', 'Jack')
    print(getattr(s, 'name'))  # Jack
    

    【示例2】使用setattr()函数为实例对象创建新的属性,代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:11
    # @Author  : AmoXiang
    # @File    : setattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
    
    s = Student()
    
    if getattr(s, 'gender', None) is None:
        setattr(s, 'gender', '男')
    
    gender = getattr(s, 'gender')
    print(gender)
    

    【示例3】结合字典的键值对,使用setattr()函数为实例对象批量创建属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:11
    # @Author  : AmoXiang
    # @File    : setattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student(object):
        def __init__(self, **dic):
            for attr, value in dic.items():
                setattr(self, attr, value)
    
    
    dict_val = {'name': 'Andy', 'age': 18, 'gender': '男'}
    s = Student(**dict_val)
    
    print(s.name)
    print(s.age)
    print(s.gender)
    

    【示例4】根据HTTP响应状态码描述获取状态码数值。HTTP 响应状态代码指示特定HTTP请求是否已成功完成。例如请求返回“404 Not Found”,其中“404”为状态码,“Not Found”为状态描述。下面的程序可以实现根据状态描述获取状态码,代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:11
    # @Author  : AmoXiang
    # @File    : setattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    _codes = {
        # 定义HTTP响应码
        200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
        400: ('bad_request', 'bad'),
        401: ('unauthorized',),
        403: ('forbidden',),
        404: ('not_found', '-o-'),
        500: ('internal_server_error', 'server_error', '/o\\', '✗'),
    }
    
    
    class LookupDict(object):
        pass
    
    
    codes = LookupDict()
    
    
    def get_code():
        for code, titles in _codes.items():  # 遍历响应码
            for title in titles:  # 遍历字典的值
                setattr(codes, title, code)  # 将其赋值为实例的title属性
                if not title.startswith(('\\', '/')):  # 处理特殊字符串
                    setattr(codes, title.upper(), code)
    
    
    get_code()  # 调用函数
    # 输出对应的响应码
    print(codes.ok)
    print(codes.okay)
    print(codes.not_found)
    print(codes.server_error)
    

    【示例5】除了可以为类添加属性外,还可以为其动态添加方法,并可以通过实例调用该方法进行相关的逻辑操作。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:11
    # @Author  : AmoXiang
    # @File    : setattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Geek:
        name = 'C灵C'
    
        def __init__(self, age):
            self.age = age
    
    
    def ge_msg(raspberry, gender):
        print(raspberry)
        return gender
    
    
    setattr(Geek, 'gender_msg', classmethod(ge_msg))  # 向类中添加一个方法,命名为gender_msg
    g = Geek(23)
    print('name: %s, age: %s, gender: %s' % (g.name, g.age, g.gender_msg('male')))
    

    3.2 delattr()函数——删除对象的属性

    delattr 函数的语法格式如下:

    参数说明:

    1. object:对象
    2. name:字符串,希望删除属性的名称
    3. 返回值:None

    说明: delattr(x, 'foobar') 相等于 del x.foobar, 删除不存在的属性会报错。

    【示例1】删除类属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
        def __str__(self):
            return "name: {}, age = {}".format(self.name, self.age)
    
    
    # Before: ['__module__', 'name', 'age', '__str__', '__dict__', '__weakref__', '__doc__']
    print("Before:", list(Student.__dict__))
    try:
        delattr(Student, 'age')  # 删除类属性
    except AttributeError as e:
        print('该类 age 属性不存在:', e)
    # Middle: ['__module__', 'name', '__str__', '__dict__', '__weakref__', '__doc__']
    print("Middle:", list(Student.__dict__))
    delattr(Student, "__str__")  # 删除类方法
    try:
        delattr(Student, '__init__')  # 所删除属性不存在,则报错
    except AttributeError as e:
        # 该类的 __init__ 属性不存在 : type object 'Student' has no attribute '__init__'
        print('该类的 __init__ 属性不存在 :', e)
    # End:    ['__module__', 'name', '__dict__', '__weakref__', '__doc__']
    print("End:   ", list(Student.__dict__))
    

    【示例2】使用delattr()函数删除对象属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return "name: {}, age = {}".format(self.name, self.age)
    
    
    obj = Student("amo", 18)  # 创建学生对象
    print("Before:", list(obj.__dict__))
    try:
        delattr(obj, 'age')  # 删除对象属性
    except AttributeError as e:
        print('该类对象 age 属性不存在:', e)
    print("Middle:", list(obj.__dict__))
    try:
        delattr(obj, 'salary')  # 所删除属性不存在, 则报错
    except AttributeError as e:
        print('该类对象的 salary 属性不存在 :', e)
    print("End:   ", list(obj.__dict__))
    

    【示例3】使用delattr()函数删除模块对象的属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    import sys
    
    
    class Student:
        name = 'Andy'
        age = 18
    
    
    obj = sys.modules[__name__]  # 获取当前模块对象
    print("Before:", list(obj.__dict__))
    try:
        delattr(obj, 'Student')  # 删除模块对象属性——Student 类
    except AttributeError as e:
        print('该模块对象 Student 属性不存在:', e)
    print("Middle:", list(obj.__dict__))
    try:
        delattr(obj, 'salary')  # 所删除属性不存在, 则报错
    except AttributeError as e:
        print('该模块对象的 salary 属性不存在 :', e)
    print("End:   ", list(obj.__dict__))
    

    【示例4】使用delattr()函数删除子类所继承的属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class School:  # 父类
        father = 100
    
        def __init__(self):
            self.position = "ChongQing City"
            self.level = "first to first"
    
    
    class Student(School):  # 子类
        son = 200
    
        def __init__(self):
            # 执行父类 __init__() 方法
            super(Student, self).__init__()
            self.name = "amo"
            self.age = 100
    
    
    obj = Student()  # 创建子类对象
    print("Before:", list(obj.__dict__))
    try:
        delattr(obj, 'level')  # 删除子类对象所继承的实例属性——level
    except AttributeError as e:
        print('该对象继承的 level 属性不存在:', e)
    print("Middle:", list(obj.__dict__))
    print("子类对象获取父类类属性 father = ", obj.father)
    print("使用子类类名获取父类的类属性:father = ", Student.father)
    try:
        delattr(obj, 'father')  # 删除子类对象所继承的类属性时报错,
    except AttributeError as e:
        print('该对象的 father 属性不存在 :', e)
    try:
        delattr(Student, 'father')  # 删除子类所继承的父类的类属性时报错,
    except AttributeError as e:
        print('该类父类的 father 属性不存在 :', e)
    print("End:   ", list(obj.__dict__))
    

    【示例5】删除新增的类和实例属性。Python是一个非常具有活力的动态语言,其在运行时可以根据需求改变结构,例如动态添加和删除类与实例的属性和方法,具体方法可参考如下代码:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Person(object):
        sex = 'male'  # 类属性
    
        def __init__(self, name):
            self.name = name
    
    
    p = Person("jerry")  # 生成一个实例
    print("My name is %s,My sex is %s" % (p.name, p.sex))
    p.age = 23  # 定义类的新属性
    print("My age is:", p.age)
    delattr(p, "age")  # 删除实例属性
    delattr(Person, "sex")  # 删除类属性
    
    # 下面代码会报AttributeError,因为age和sex两个属性已成功删除
    print("My age is %s,My sex is %s" % (p.age, p.sex))
    

    【示例6】delattr()函数的功能基本同 del运算符一致,仅多了一条动态属性删除的功能。除此之外,可以使用 del 运算符来实现相同的删除效果,并且占用的字节码指令更少,执行速度更高。测试代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 9:05
    # @Author  : AmoXiang
    # @File    : delattr_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Person(object):
        name = 'C灵C'  # 类属性
    
    
    p = Person()  # 生成一个实例
    for i in range(1000):  # 生成测试数据
        a = 'attr_' + str(i)
        setattr(p, a, i)  # 设置新属性
    
    note = input('请选择删除方法(1.delattr()函数, 2.del运算符):')
    if note == '1':
        for j in range(1000):
            k = 'attr_' + str(j)
            delattr(p, k)  # 动态删除属性
        print('delattr()函数已完成删除')  # 在测试效率时,尽量不要包含print()函数
    elif note == '2':
        for j in range(1000):
            k = 'attr_' + str(j)
            del p.k  # 此行代码会报AttributeError错误,不能动态删除属性
        print('del运算符已完成删除')
    

    3.3 hasattr()函数——检查对象是否含有属性

    hasattr 函数的语法格式如下:

    参数说明:

    1. object:对象
    2. name:字符串,属性名
    3. 返回值:如果对象有该属性返回 True,否则返回 False

    【示例1】使用hasattr()函数判断是否属性为原生类型属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    str_val = 'hasattr'
    print(hasattr(str_val, '__len__'))  # 输出为True
    print(hasattr(str_val, '__lt__'))  # 输出为True
    print(hasattr(str_val, 'format'))  # 输出为True
    print(hasattr(str_val, 'lower'))  # 输出为True
    
    list_val = [1, 2, 3]
    print(hasattr(list_val, '__len__'))  # 输出为True
    print(hasattr(list_val, '__delitem__'))  # 输出为True
    print(hasattr(list_val, 'pop'))  # 输出为True
    
    dict_val = {'name': 'Andy'}
    print(hasattr(dict_val, '__len__'))  # 输出为True
    print(hasattr(dict_val, 'keys'))  # 输出为True
    print(hasattr(dict_val, 'values'))  # 输出为True
    

    【示例2】使用hasattr()函数判断属性是否为类属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
        def hello(self):
            print('hello')
    
    
    print(hasattr(Student, 'name'))  # True
    print(hasattr(Student, 'age'))  # True
    print(hasattr(Student, 'hello'))  # True
    print(hasattr(Student, 'hi'))  # False
    

    【示例3】使用hasattr()函数判断是否为实例属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class Student:
        name = 'Andy'
        age = 18
    
        def hello(self):
            print('hello')
    
    
    s = Student()
    # 判断是否属于实例的属性
    print(hasattr(s, 'name'))  # True
    print(hasattr(s, 'age'))  # True
    print(hasattr(s, 'hello'))  # True
    print(hasattr(s, 'hi'))  # False
    

    【示例4】使用hasattr()函数判断属性是否继承父类属性。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class A:
        a_name = 'A'
    
        def a_test(self):
            pass
    
    
    class B(A):
        b_name = 'B'
    
        def b_test(self):
            pass
    
    
    print(hasattr(B, 'a_name'))  # True
    print(hasattr(B, 'a_test'))  # True
    print(dir(B()))
    

    【示例5】获取表格每列的宽度。在绘制表格时,为了使表格展示美观,通常需要获取每一列中的最长宽度,然后再绘制表格。如果该表格有表头,那么每一列的最长宽度可能是表头的长度,也可能是表格中内容的长度。下面的代码可以实现该功能:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    def _max_word_len(text):
        '''获取单词的最大长度'''
        return max((len(word) for word in text.split()))
    
    
    def _get_column_string_lengths(dataset):
        """返回每一列的字符串长度和该列的字符串长度最大值"""
        if dataset.headers:  # 判断表头是否存在
            # 获取表头列的长度
            column_lengths = [[len(h)] for h in dataset.headers]
            # 获取表头每列的单词长度
            word_lens = [_max_word_len(h) for h in dataset.headers]
        for row in dataset.dict:  # 遍历每一行
            # 如果row对象包含values属性,则创建生成器
            values = iter(row.values() if hasattr(row, 'values') else row)
            # 遍历字典的值
            for i, val in enumerate(values):
                text = str(val)  # 转化为字符串
                column_lengths[i].append(len(text))  # 加入列表
                word_lens[i] = max(word_lens[i], _max_word_len(text))  # 获取最大长度
        return column_lengths, word_lens
    
    
    class Dateset(object):
        pass
    
    
    ds1 = Dateset()  # 实例化Dateset类
    ds1.headers = ("first_name", "last_name", "age")  # 动态条件headers属性
    # 动态添加dict属性
    ds1.dict = [{'first_name': 'andy', 'last_name': 'feng', 'age': 18},
                    {'first_name': 'Alexandra', 'last_name': 'Gwenhwyfar', 'age': 30}]
    # 输出每列的字符串长度,以及字符串长度的最大值
    print(_get_column_string_lengths(ds1))
    # ([[10, 4, 9], [9, 4, 10], [3, 2, 2]], [10, 10, 3])
    # 说明: 在运行结果的列表中,有2个元素。第1个元素是每1列的长度(包括表头、内容的长度),第2个是元素是第1列的最大值。
    

    【示例6】在操作一些特殊文件时,通常需要判断一个文件是否具备读写的权限。可以通过hasattr()函数来实现该功能。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 8:50
    # @Author  : AmoXiang
    # @File    : hasattr.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    
    class FileProxyMixin:
        def __init__(self, file):
            """
            初始化方法
            :param file: 文件对象
            """
            self.file = file
    
        @property
        def closed(self):
            return not self.file or self.file.closed
    
        def readable(self):
            # 如果文件关闭,返回False
            if self.closed:
                return False
            # 判断是否有'readable'属性
            if hasattr(self.file, 'readable'):
                return self.file.readable()
            return True
    
        def writeable(self):
            # 如果文件关闭,返回False
            if self.closed:
                return False
            # 判断是否有'writeable'属性
            if hasattr(self.file, 'writeable'):
                return self.file.writable()
            return 'w' in getattr(self.file, 'mode', '')
    
    
    if __name__ == "__main__":
        file_name = 'hello.txt'
        # 判断文件是否可读
        with open(file_name) as f:
            file = FileProxyMixin(f)
            if file.readable():
                print(f'{file_name}文件是可读文件')
            else:
                print(f'{file_name}文件是不可读文件')
        # 判断关闭文件后,是否可写
        with open(file_name) as f:
            # 关闭文件
            print('关闭文件')
            f.close()
            file = FileProxyMixin(f)
            # 判断是否可写
            if file.writeable():
                print(f'{file_name}文件是可写文件')
            else:
                print(f'{file_name}文件是不可写文件')
    

    3.4 vars()函数——获取对象的属性和属性值

    vars 函数的语法格式如下:

    参数说明:

    1. object:对象
    2. 返回值:如果没有实参,则返回当前本地作用域中的属性和属性值的字典对象;如果有实参,则返回该对象 object 的属性和属性值的字典对象

    【示例1】vars()函数在类继承中的表示。使用vars()函数分别输出子类、子类对象、父类、父类对象的属性字典对象。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 18:04
    # @Author  : AmoXiang
    # @File    : vars_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    class Leg:  # 父类
        num = 2
    
        def __init__(self):
            self.is_sickness = False
    
    
    class Person(Leg):  # 子类
        posi = "ChongQing"
    
        def __init__(self):
            super(Person, self).__init__()
            self.salary = 500000
    
    
    person = Person()  # 创建子类对象
    leg = Leg()
    obj_01, obj_02 = vars(Person), vars(person)
    obj_03, obj_04 = vars(Leg), vars(leg)
    print("   子类 vars() = {} \n子类对象vars() = {}".format(obj_01, obj_02))
    print("   父类 vars() = {} \n父类对象vars() = {}".format(obj_03, obj_04))
    print(obj_02["is_sickness"])  # 获取属性值
    obj_02["is_sickness"] = True  # 修改属性值
    print(obj_02["is_sickness"])
    

    【示例2】vars()与类的 __dict__ 属性。在 Python中,类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都放在类的 __dict__ 属性里,但一些内置的数据类型是没有 __dict__ 属性的。若在使用vars()函数时传入自定义类(大多数自定义类会隐式创建 __dict__ 属性)的对象,则返回对象的 __dict__ 属性;若传入一些内置的数据类型,则由于其没有 __dict__ 属性,就会提示 TypeError 错误。代码如下:

    # -*- coding: utf-8 -*-
    # @Time    : 2025-05-01 18:04
    # @Author  : AmoXiang
    # @File    : vars_demo.py
    # @Software: PyCharm
    # @Blog: https://blog.csdn.net/xw1680
    
    x = 1
    a = vars()  # 未传入参数,作用相当于locals()
    if a == locals():
        b = a['x']
        print(b)
    
    
    class VarsDict:
        def __init__(self):
            self.__dict__ = {'': '调用了__dict__属性'}
    
    
    c = VarsDict()
    d = vars(c)  # 返回字典对象
    print(d)
    vars(True)  # 传入Python内置的数据类型,由于内置的数据类型是没有__dict__属性,所以此处会报TypeError错误
    

    作者:Amo Xiang

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python对象属性操作详解:探讨内置函数getattr、setattr、delattr、hasattr与vars的使用与功能

    发表回复