DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • python面向过程

  • python面向对象

    • OOP基本
    • 继承和组合
    • 多态与多态性
    • 封装与接口
    • 绑定与非绑定方法
    • 简单总结
    • 反射、内置方法
      • 反射
        • 操作属性
        • 反射简单应用
      • 内置方法
        • __str__
        • __del__
    • 元类
    • 异常处理
    • 小项目之course_select
    • 复习
  • 网络并发编程

  • 不基础的py基础

  • 设计模式

  • python_Need
  • python面向对象
DC
2023-07-26
目录

反射、内置方法

# 反射

通过 字符串 来操作类或者对象的属性
涉及四个内置函数: hasattr      getattr      setattr      delattr

>>> hasattr
<built-in function hasattr>
1
2

# 操作属性

注意, 使用 getattr时候, 必须捕获的到的是 AttributeError 异常, 才能返回getattr设置的第三个参数值!!
就像是 自定义迭代器要raise StopIteration一样, 只有这样for循环才会捕捉到并终止迭代!!

xxx = 1

class Pepole:
    country = 'china'

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

    def eat(self):
        print(f"{self.name} is eating!")


p = Pepole('dc')
# -- 本质上是看 p能否对country这个属性进行引用 不局限于判断 "country" in p.__dict__
#    也就是在判断能否通过.访问到某个属性 即p.country是否报错 
#    回顾下属性查找规则(命名空间): 自身-类-父类-...-顶级父类object
print(hasattr(p, "country"))  # True
print(hasattr(p, "xxx"))      # False

# <bound method Pepole.eat of <__main__.Pepole object at 0x7f8adde7e910>>
print(getattr(p, "eat"))
print(p.eat)  # <bound method Pepole.eat of <__main__.Pepole object at 0x7f8adde7e910>>
# print(getattr(p, "xxx"))  # AttributeError:'Pepole' object has no attribute 'xxx'
print(getattr(p, "xxx", "没有该属性"))  # 没有该属性 -- 通常情况下没找到会设置返回值为None

setattr(p, "age", 18)  # -- 等同于 p.age = 18
print(p.age)  # 18

print(p.__dict__)  # {'name': 'dc', 'age': 18}
delattr(p, "name")  # -- 等同于 del p.name
print(p.__dict__)  # {'age': 18}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 反射简单应用

这个例子很好的诠释了 反射比点语法好的地方!! 因为反射的第二个参数是字符串!!

class Ftp:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    def get(self):
        print("GET function")

    def put(self):
        print("PUT function")

    def run(self):
        while True:
            # -- 输入字符串反射到对象具体的方法上面
            choice = input(">>>: ").strip()
            if hasattr(self, choice):
                method = getattr(self, choice)
                method()
            else:
                print("您输入的命令不存在!")
            """
            method = getattr(self, choice, None)
            if method:
                method()
            else:
                print("不存在")
            """

conn = Ftp("1.1.1.1", 3306)
conn.run()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 内置方法

自定义内置方法来定制类的功能
以__开头和__结尾的方法在满足某种条件下会自动触发.

# __str__

d = {'x': 1}  # -- 即d = dict({'x':1}) 调用dict这个类来完成实例化的过程
print(d)  # {'x': 1} -- d是一个对象,本质是一个命名空间,里面存的是一堆数据


"""
像内置数据类型一样,在打印对象时,打印有用的信息出来.而不是打印内存地址.
__str__ 为打印对象定制打印的格式
"""
class People:

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

    # -- 在对象self被打印时,自动触发
    #    在顶级父类object中有__str__方法,返回的是self的内存地址
    #    我们应该重写该方法,在该方法内采集与对象self有关的信息,然后拼成字符串返回
    def __str__(self):
        return "name:%s,age:%s" % (self.name, self.age)


obj = People('dc', 18)
# -- 没有__str__方法的时候,打印 <__main__.Foo object at 0x7fef48e8d1f0>
#    有__str__方法后, name:dc,age:18
print(obj)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# __del__

__del__ 析构方法. 会在对象被删除之前自动触发
应用场景:
       该对象不仅仅占用python应用程序的内存空间,还占用其他(eg:操作系统)的资源.
       需要在回收该对象时候,使用析构方法将占用的其他资源顺带一起回收了..

__del__会在对象被删除时自动触发.
由于Python自带的垃圾回收机制会自动清理Python程序的资源
所以当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法.
但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下
【关于系统资源的回收,Python的垃圾回收机制便派不上用场了?? "这句话好像不严谨"】
需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作!!
"""
f = open('a.txt') 可以看作一个类实例化得到了f对象
f对象占用两方面的资源:
  1> f是python的一个变量名,占用python应用程序的空间
  2> f还对应操作系统打开的a.txt文件
申请资源后,需要回收资源:
  1> 针对变量的回收,python有gc机制,能回收变量对应的值
  2> 操作系统方面的资源 在f变量被回收之前,通过f.close()进行回收
"""
f = open('a.txt')


class People:

    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.f = open('a.txt', 'rt', encoding='utf-8')

    def __del__(self):
        self.f.close()

    def __str__(self):
        return "name:%s,age:%s" % (self.name, self.age)


# -- obj是python应用程序的资源,没必要考虑回收
#    但是obj里面有属性f,该属性不仅占用python资源,还指向操作系统打开的文件
obj = People('dc', 18)
# -- 方式1> 程序结束,自动回收 命名空间生命周期结束,引用计数为0,回收
# -- 方式2> 程序当中,主动删除对象,使用del解除对象与值的绑定关系,该对象则会被gc机制自动回收
del obj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

简单总结
元类

← 简单总结 元类→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式