惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
J
Java Code Geeks
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
Blog — PlanetScale
Blog — PlanetScale
G
Google Developers Blog
WordPress大学
WordPress大学
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
T
Tor Project blog
阮一峰的网络日志
阮一峰的网络日志
Recent Commits to openclaw:main
Recent Commits to openclaw:main
The Hacker News
The Hacker News
F
Full Disclosure
有赞技术团队
有赞技术团队
H
Help Net Security
Security Latest
Security Latest
P
Palo Alto Networks Blog
MyScale Blog
MyScale Blog
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
P
Privacy International News Feed
P
Proofpoint News Feed
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
罗磊的独立博客
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
Latest news
Latest news
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
T
Threat Research - Cisco Blogs
Last Week in AI
Last Week in AI
The Last Watchdog
The Last Watchdog
N
Netflix TechBlog - Medium
D
DataBreaches.Net
L
LINUX DO - 热门话题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
L
Lohrmann on Cybersecurity
O
OpenAI News
S
SegmentFault 最新的问题
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

郑文峰的博客

使用dify对接飞书多维表格 使用n8n对接飞书多维表格 服务启动时出现 OOM 一次服务升级时pg表DDL执行超时失败 Go语言高效IO缓冲技术详解 Go语言延迟初始化(Lazy Initialization)最佳实践 Go语言字符串拼接性能对比与优化指南 Go语言结构体内存对齐完全指南 Go语言空结构体:零内存消耗的高效编程 Go语言堆栈分配与逃逸分析深度解析 Go语言原子操作完全指南 Go语言内存预分配完全指南 Go语言不可变数据共享:无锁并发编程实践 Go语言零拷贝技术完全指南 Go语言遍历性能深度解析:从原理到优化实践 Go语言Interface Boxing原理与性能优化指南 Go协程池深度解析:原理、实现与最佳实践 使用etcd分布式锁导致的协程泄露与死锁问题 基于pre-commit的Python代码规范落地实践 初识 MCP Server pulsar阻塞导致logstash无法接入日志 django-prometheus使用及源码分析 kube-proxy源码分析 kubernetes service如何通过iptables转发 tcp缓存引起的日志丢失 django-apschedule定时任务异常停止 理解calico容器网络通信方案原理 理解flannel的三种容器网络方案原理 理解Linux IPIP隧道 理解VXLAN网络 理解Linux TunTap设备 快速了解iptables kafka中listener和advertised.listeners的作用 django rest_framework 分页 django后端服务、logstash和flink接入VictoriaMetrics指标监控 python中import原理 docker容器单机网络 手动实现docker容器bridge网络模型 mysql之MVCC原理 mysql之日志 使用java开发logstash的filter插件 使用python实现单例模式的三种方式 redis之缓存 redis之分片集群 redis之哨兵机制 redis之主从库同步 redis之持久化 redis之五种基本数据类型 go中如何处理error pod中将代码与运行环境分离 ddt源码分析 python装饰器的使用方法 读书笔记:如何阅读一本书 使用ddt实现unittest的参数化测试 使用kubeadm安装k8s 优化gin表单的错误提示信息 gin中validator模块的源码分析 go简单使用grpc python简单使用grpc k8s之PV、PVC和StorageClass k8s之StatefulSet k8s之DaemonSet k8s之Job和CronJob k8s之ConfigMap和Secret k8s之Service k8s之Pod k8s之Deployment 容器的本质 docker容器 python迭代器与生成器 python垃圾回收机制 python上下文管理器 django rest_framework使用jwt django rest_framework异常处理 django rest_framework 自定义文档 django压缩文件下载 django rest_framework使用pytest单元测试 django restframework choice 自定义输出数据 django Filtering 使用 django viewset 和 Router 配合使用时报的错 django model的序列化 django中使用AbStractUser django.core.exceptions.ImproperlyConfigured Application labels aren't unique, duplicates users django 中 media配置 django 外键引用自身和on_delete参数 django 警告 while time zone support is active Flask使用flask_socketio实现websocket flask结合mongo tornado 文件上传 tornado 使用jwt完成用户异步认证 tornado 用户密码 bcrypt加密 tornado 结合wtforms使用表单操作 tornado finish和write区别 tornado 使用peewee-async 完成异步orm数据库操作 pyspark streaming简介 和 消费 kafka示例 使用hue创建ozzie的pyspark action workflow count的性能优化 django rest_framework Authentication django celery 结合使用 网站
python元编程
zhengwenfeng · 2022-08-10 · via 郑文峰的博客

# property动态属性

通过使用property可以将方法像属性一样获取值。使用setter对方法进行赋值操作


from datetime import datetime, date
class Student:

    def __init__(self, name, birthday):
        self.name = name
        self.birthday = birthday
        self._age = 0
    
    @property
    def age(self):
        return datetime.now().year - self.birthday.year
    
    @age.setter
    def age(self, value):
        self._age = value
    
stu = Student("zhangsan", date(year=1995, month=3, day=7))
stu.age = 4
print(stu.age)

output: 24

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# getattributegetattr

__getattr__在类中找不到属性时,调用该函数。 __getattribute__首先调用该函数,然后找属性.

__getattribute__中抛出AttributeError时,会调用__getattr__

调用顺序 __getattribute__ > __getattr__

# 属性描述符

在类中只要实现了__get____set____delete__方法中的一个就认为是描述符. 只实现了__get__的对象是非数据描述符. 只读 实现了__get____set__的对象是数据描述符. 可读可写.

class IntField:
    def __get__(self):
        pass
        
    def __set__(self):
        pass
        
    def __delete__(self):
        pass

1
2
3
4
5
6
7
8
9

# 属性描述符查找过程

属性描述符发生的过程在__getattribute__中.

如果age是属性描述符,则调用IntField中的__get__获得属性值,如果获取失败,则调用__dict__获取值。如果age不是属性描述符,则直接获取__dict__对应的值。


import numbers
class IntField:
    # 数据描述符
    def __get__(self, instance, owner):
        return self.value
        
    def __set__(self, instance, value):
        if not isinstance(value, numbers.Integral):
            raise ValueError("int value need")
        if value < 0:
            raise ValueError("positive value need")
        self.value = value
        
    def __delete__(self, instance):
        pass
    
class NonDataIntField:
    # 非数据属性描述符
    def __get__(self, instance, owner):
        return "NonDataIntField = {}".format(self.value)

class User:
    age = IntField()
    #age = NonDataIntField()

user = User()
user.name = "zhangsan"    # name不是属性描述符,所以直接加入到`__dict__`中
print(user.__dict__)

user.age = 12               # age是属性描述符, 调用`IntField`中的`__set__`方法, 而不会加入到`__dict__`中
print(user.__dict__)
print(user.age)              # 调用`IntField`中的`__get__`方法


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

# 元类

元类是创建类的类. type -> class -> 对象

所有的类都是通过type实例化得到的。

# 通过type创建class

使用type创建User类,该类继承Base类,并且有test方法和name属性


class Base:
    def __init__(self, *args, **kwargs):
        print("Base __init__")
        super().__init__(*args, **kwargs)

def test(self):
    print("test = {}".format(self.name))
 
User = type("User", (Base,), {"test": test, "name": "zhangsan"})
user = User()
user.test()


1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 自定义元类

自定义元类需要通过继承type实现

如果父类有metaclass,则子类和父类的创建都需要通过该元类实例化得到。



class BaseMeta(type):

    def __new__(cls, name, bases, args, **kwargs):
        # print(name)
        # print(bases)
        # print(args)
        print("BaseMeta __new__..")
        
        if name == "Base":
            return super().__new__(cls, name, bases, args, **kwargs)
            
        meta = args['Meta']
        name = getattr(meta, "name")    # 获取到A中meta的name的值. django的orm也是这样实现的
        print(name)
        
        return super().__new__(cls, name, bases, args, **kwargs)



class Base(metaclass=BaseMeta):

    def __new__(cls, *args, **kwargs):
        print("Base __new__..")
        return super().__new__(cls, *args, **kwargs)
        
    def __init__(self, *args, **kwargs):
        print("Base init..")
        super().__init__(*args, **kwargs)
    
class A(Base):

    def __new__(cls, *args, **kwargs):
        print("A __new__..")
        return super().__new__(cls, *args, **kwargs)
        
    def __init__(self, *args, **kwargs):
        print("A init..")
        super().__init__(*args, **kwargs)
        
    class Meta:
        name = "zhangsan"


# A和Base都会通过BaseMeta创建,所以会调用两次__new__创建实例
output:

BaseMeta __new__..
BaseMeta __new__..
zhangsan

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
39
40
41
42
43
44
45
46
47
48
49
50
51

元类的经典例子是django ORM