news 2026/4/16 15:38:58

python,类和实例的一些学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python,类和实例的一些学习笔记

类属性和实例属性的关系

  • 一段代码:
class Person: name = "PersonClass" # 类属性 def __init__(self, name=""): self.name = name # 实例属性 # 创建实例 p = Person("小明") print(f"类属性:", Person.name) print(f"实例属性:", p.name)
  • 代码逐行解析
  1. 类的定义与类属性

    class Person: name = "PersonClass" # 类属性
    • class Person:定义了一个名为Person的类,类是创建对象(实例)的模板。
    • name = "PersonClass"类属性:属于整个Person类,所有基于这个类创建的实例,在没有自己的同名实例属性时,都能访问到这个值;类属性也可以直接通过类名.属性名访问。
  2. 初始化方法与实例属性

    def __init__(self, name=""): self.name = name # 实例属性
    • __init__是 Python 类的构造方法(初始化方法),创建实例时会自动执行。
    • self代表当前创建的实例本身,是必传的第一个参数。
    • self.name = name实例属性:属于每个独立的实例,不同实例的这个属性可以有不同的值;实例属性必须通过实例名.属性名访问。
    • name=""给参数设置了默认值,创建实例时如果不传name,实例属性name就为空字符串。
  3. 创建实例与打印属性

    p = Person("小明") print(f"类属性:", Person.name) print(f"实例属性:", p.name)
    • p = Person("小明")创建了Person类的一个实例p,并把"小明"传给__init__name参数,此时实例pname属性被赋值为"小明"
    • Person.name直接访问类属性,结果是"PersonClass"
    • p.name访问实例p的实例属性,结果是"小明"(因为实例属性会覆盖同名的类属性)。
  • 执行结果

运行这段代码会输出:

类属性: PersonClass 实例属性: 小明
  • 总结:
  1. 类属性:属于类本身,通过类名.属性名访问,是所有实例共享的;
  2. 实例属性:属于单个实例,通过实例名.属性名访问,每个实例的实例属性可以独立赋值;
  3. 当实例属性和类属性同名时,访问实例名.属性名会优先获取实例属性,类属性不受影响。
  • 补充验证,加深理解:
class Person: name = "PersonClass" # 类属性 def __init__(self, name=""): self.name = name # 实例属性 # 创建实例 p = Person("小明") # 直接访问实例的 name 属性:优先取实例属性 print(p.name) # 输出:小明 # 删除实例的 name 属性后,实例会访问类属性 del p.name print(p.name) # 输出:PersonClass

类方法和实例方法的关系

class Person: name = "PersonClass" # 类属性 def __init__(self, name=""): self.name = name # 实例属性 # 类方法 @classmethod def get_cls_name(cls): return cls.name # 实例方法 def get_self_name(self): return self.name # 创建实例 p = Person("小明") print(f"类方法:", Person.get_cls_name()) print(f"类方法:", p.get_cls_name()) print(f"实例方法:", p.get_self_name())
  • 代码解析:

1. 类方法定义与调用

# 类方法:第一个参数是cls(代表类本身),类与类的实例均可调用 @classmethod def get_cls_name(cls): return cls.name # 调用类方法 print(f"类方法:", Person.get_cls_name()) # 类直接调用:cls = Person,返回类属性 name print(f"类方法:", p.get_cls_name()) # 实例调用:cls 自动指向实例所属的类(Person),仍返回类属性
  • @classmethod的含义是:本方法被声明为类方法。
  • 类方法的核心是cls参数:无论用类(Person)还是实例(p)调用,cls始终指向类本身(而非实例),因此cls.name永远取的是类属性Person.name,而非实例属性p.name

2 .实例方法定义与调用

# 实例方法:第一个参数是self(代表实例本身),只能用实例调用 def get_self_name(self): return self.name # 调用实例方法 print(f"实例方法:", p.get_self_name()) # 实例调用:self = p,返回实例属性 name(小明)
  • 实例方法的核心是self参数:必须用实例(p)调用,self指向当前实例,因此self.name取的是实例自己的属性(小明),而非类属性。
  • 总结
  1. 类属性 vs 实例属性:类属性属于类,所有实例共享;实例属性属于单个实例,优先级高于同名类属性。
  2. 类方法:用@classmethod装饰,参数是cls(指向类),类 / 实例均可调用,操作的是类属性。
  3. 实例方法:参数是self(指向实例),只能用实例调用,操作的是实例属性(或类属性)。

类方法与静态方法的关系

class Person: name = "PersonClass" def __init__(self, name): self.name = name # 类方法 @classmethod def class_method(cls): cls.name = "PersonClass" return cls.name # 可以通过cls来传递和操作类属性 # 静态方法 @staticmethod def static_method(): Person.name = "PersonStatic" # 除非直接写类名,否则无法操作类属性(可以但不推荐) return Person.name # 创建实例 p = Person("小明") # 访问类的类方法 print(Person.class_method()) # 输出:PersonStatic # 访问类的静态方法 print(Person.static_method()) # 输出:PersonStatic # 访问实例的类方法 print(p.class_method()) # 输出:PersonStatic # 访问实例的静态方法 print(p.static_method()) # 输出:PersonStatic
  • 关键细节解释:

1 . 类方法的核心:cls参数

  • cls是自动传入的,指向调用该方法的类
  • 即使通过实例调用,cls依然指向Person类,因此能稳定访问类属性;

2. 静态方法的核心:无绑定参数

  • 静态方法本质是 “挂在类名下的普通函数”,和类的关联仅在于 “归类管理”;
  • 不能直接访问类属性 / 实例属性(除非手动写Person,但不推荐);

3.什么时候用哪个?

  • 如果需要操作类属性(读 / 改),或需要创建类的实例→ 用类方法;
  • 如果你需要一个和类相关但不依赖类 / 实例属性的工具函数 → 用静态方法;
  • 如果你需要操作实例属性→ 用普通实例方法(self参数)。

使用setattr()方法动态设定/修改类方法和静态方法

  • 将一个函数用classmethod()定义为类方法,就可以在方法中操作类属性:
class Person: def __init__(self, name): self.name = name # 只定义了一个实例方法,没有定义类方法 # 创建实例 p = Person("小明") def class_method(cls): cls.name = "PersonClass" # 添加一个类属性 setattr(Person, "class_method", classmethod(class_method)) # Person.class_method() # 用类调用类方法 p.class_method() # 用实例调用类方法也可以 print(Person.name) # 输出:PersonClass print(p.name) # 输出:小明
  • 将一个函数用staticmethod()定义为静态方法,就可以修改或新建类的静态方法:
class Person: def __init__(self, name): self.name = name # 只定义了一个实例方法,没有定义类方法 @staticmethod def static_method(): print("static_method") # 创建实例 p = Person("小明") # 定义一个新的静态方法 def new_static_method(): print("new_static_method") setattr(Person, "static_method", staticmethod(new_static_method)) # 使用类或者实例都可以调用静态方法 p.static_method() # 输出:new_static_method Person.static_method() # 输出:new_static_method

使用setattr()方法动态修改类的实例方法

  • 将一个函数用types.MethodType()定义以后,就可以修改(或新建)类的实例方法:
import types class Person: def __init__(self, name): self.name = name # 只定义了一个实例属性,没有定义方法 # 创建实例 p = Person("小明") # 定义一个实例方法 def set_age(self, age): self.age = age setattr(p, "age", int) # 动态添加实例的属性 setattr(p, "set_age", types.MethodType(set_age, p)) # 动态绑定实例的方法 p.set_age(10) # 调用实例的新方法 print(f"名字:{p.name},年龄:{p.age}") # 输出:名字:小明,年龄:10

注意:types.MethodType是单例生效的,只对当前传入的实例 (p) 生效。

  • 如果需要对类的所有新建实例都生效:
class Person: def __init__(self, name): self.name = name # 只定义了一个实例属性,没有定义方法 # 定义一个实例方法 def set_age(self, age): self.age = age setattr(Person, "age", int) # 动态添加实例的属性 setattr(Person, "set_age", set_age) # 动态绑定实例的方法 p = Person("小红") p.set_age(20) # 调用实例的新方法 print(f"名字:{p.name},年龄:{p.age}") # 输出:名字:小红,年龄:20
  • Qt窗口部件实例,动态修改其事件处理函数的范例
import sys import types from PySide6.QtCore import Slot from PySide6.QtWidgets import QApplication, QWidget, QMessageBox @Slot() def close_event(self, event): # 弹出确认对话框 reply = QMessageBox.question( self, "确认", "确定要关闭窗口吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No # 默认选中No ) # 根据用户选择决定是否关闭窗口 if reply == QMessageBox.Yes: event.accept() # 接受关闭事件 else: event.ignore() # 忽略关闭 app = QApplication(sys.argv) window = QWidget() window.show() setattr(window, "closeEvent", types.MethodType(close_event, window)) # 动态绑定窗口部件的关闭事件处理函数 sys.exit(app.exec())

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:21:37

计算机Java毕设实战-基于Springboot框架下中药材科普系统的开发与应用基于springboot的中药科普知识平台的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/4/16 9:22:59

改进的USBASP模块

简 介: 本文介绍了改进版USBASP下载模块的制作过程。主要改进包括:将12MHz晶体改为表贴式以缩小体积,增加独立负载电源接口,在USB D-线添加上拉电阻使Mega8可识别为低速USB模式,优化跳线设计实现单面PCB制作。通过一分…

作者头像 李华
网站建设 2026/4/16 9:21:56

AI4Science的前沿公司:Polymathic AI

1. 摘要 在当前的人工智能(AI)浪潮中,公众与市场的目光往往聚焦于以大语言模型(LLM)为代表的生成式 AI,其商业逻辑通常围绕“软件即服务”(SaaS)或API调用的变现模式展开。然而&…

作者头像 李华
网站建设 2026/4/16 9:26:23

1.2 一句话说清 Agent 和普通程序到底差在哪

1.2 一句话说清:Agent 和普通程序到底差在哪 本节学习目标 用一句话精确定义 Agent,并能向他人解释清楚。 掌握 Agent 的四大核心属性:自主感知、决策、行动、目标导向。 能区分「传统程序 / 传统自动化」与「Agent」,避免概念混淆。 一、一句话定义 一句话:Agent 是在给…

作者头像 李华
网站建设 2026/4/16 10:43:27

第1章 程序点滴程序点滴-1.1 程序≠软件(2)

1.1.2 认清自己的发展如果连以上认识都不清楚,很可能就以为去书店买一本MFC高手速成之类的书,编两个程序就能成为软件高手。就好像这些书是“黄金”,我学两下,学会了VC、MFC,就能做一个软件拿出去卖了。这种想法也不是…

作者头像 李华