当前位置: 首页 > article >正文

Python基础:python的self是啥 附:含数据接收、解码和保存例子(基础)

python的self是啥

文章目录

  • python的self是啥
    • 前言:跟着伊希尔老师做python的数据接收、解码和保存
    • 一、问题缘起:从self.socket-->socket是方法集合,那self是啥
      • 是一个简化版的数据流例子
      • 例子代码
    • 二、解释self
      • 2.1 解答:在 Python 中,`self` 是一个特殊的参数,它代表类的实例本身。
      • 2.2 初步理解: 那就是类中的方法,有两个参数self和name(假设),此时可只传name参数,就能达到方法不同传参的同一个方法使用,约等于去掉self,这个方法实际参数只有一个name。如此理解就可以。
      • 2.2.1 更深理解的例子辅助
      • 2.2.2 学究式理解
    • 三、回归socket的self理解:①代表实例 ②可以把 `self` 理解为 Java 中的 `this`

前言:跟着伊希尔老师做python的数据接收、解码和保存

最近跟着伊希尔老师做python的数据接收、解码和保存。由于首次使用python处理数据流,能大致理解方法作用,在具体到方法参数理解上却无法理解。我归结为对python惯例的未知导致的囫囵吞枣。这里举例我看不懂的socket对象创建及self到底是啥,进行自我理解。2024年10月30日11:51:07

一、问题缘起:从self.socket–>socket是方法集合,那self是啥

方法里,用socket对协议解析等。但socket方法前面一直跟着一个 self.socket ,但python却无参数类名体现,因为我得出疑问”self传进来是什么东西?是一个链接?一个数据?还是啥,而且java中用大写代表类型,小写代表对象。python中我不理解这个是啥意思“,具体例子如下

是一个简化版的数据流例子

简化版:
1、直接保存接收到的数据
2、简单的文件存储
3、基本的多线程处理
4、没有特定的数据格式要求

例子代码

import socket
import threading
import time
import os

# 基本配置
HOST = '0.0.0.0'  # 监听所有网络接口
PORT = 9999       # 服务器端口号
SAVE_PATH = './data'  # 数据保存路径

# 确保保存目录存在
os.makedirs(SAVE_PATH, exist_ok=True)

class SimpleDataSaver:
    def __init__(self):
        """初始化数据保存器"""
        self.current_file = None
        
    def save_data(self, data, client_address):
        """保存数据到文件"""
        # 用客户端地址创建文件名
        filename = f"{SAVE_PATH}/{client_address[0]}-{client_address[1]}.txt"
        
        # 如果文件未打开,打开它
        if self.current_file is None:
            self.current_file = open(filename, 'a')
            
        # 保存数据和时间戳
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        self.current_file.write(f"{timestamp}: {data}\n")
        self.current_file.flush()  # 确保数据被写入磁盘

class SimpleTCPServer:
    def __init__(self):
        """初始化服务器"""
        # 创建TCP套接字
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 允许端口复用
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定地址和端口
        self.server_socket.bind((HOST, PORT))
        # 创建数据保存器
        self.data_saver = SimpleDataSaver()
        
    def handle_client(self, client_socket, client_address):
        """处理单个客户端连接"""
        print(f"新的连接来自: {client_address}")
        
        try:
            while True:
                # 接收数据
                data = client_socket.recv(1024)
                if not data:
                    break  # 客户端断开连接
                    
                # 将收到的字节转换为字符串
                data_str = data.decode('utf-8')
                print(f"收到数据: {data_str}")
                
                # 保存数据
                self.data_saver.save_data(data_str, client_address)
                
                # 发送确认消息
                client_socket.send("数据已收到".encode('utf-8'))
                
        except Exception as e:
            print(f"处理客户端 {client_address} 时出错: {e}")
        finally:
            client_socket.close()
            print(f"客户端 {client_address} 断开连接")
    
    def start(self):
        """启动服务器"""
        # 开始监听连接
        self.server_socket.listen(5)
        print(f"服务器正在监听 {HOST}:{PORT}")
        
        try:
            while True:
                # 等待新的连接
                client_socket, client_address = self.server_socket.accept()
                
                # 为每个客户端创建新的线程
                client_thread = threading.Thread(
                    target=self.handle_client,
                    args=(client_socket, client_address)
                )
                client_thread.daemon = True
                client_thread.start()
                
        except KeyboardInterrupt:
            print("\n服务器正在关闭...")
        finally:
            self.server_socket.close()

# 启动服务器
if __name__ == '__main__':
    server = SimpleTCPServer()
    server.start()

二、解释self

2.1 解答:在 Python 中,self 是一个特殊的参数,它代表类的实例本身。

class Dog:
    def __init__(self, name):  # self 指向被创建的实例
        self.name = name  # 将 name 保存为实例的属性
    
    def bark(self):  # self 指向调用这个方法的实例
        print(f"{self.name}: 汪汪!")

# 创建实例
dog1 = Dog("小黑")  # Python 自动把创建的实例传给 self
dog2 = Dog("小白")

# 调用方法
dog1.bark()  # 输出: 小黑: 汪汪!
dog2.bark()  # 输出: 小白: 汪汪!

2.2 初步理解: 那就是类中的方法,有两个参数self和name(假设),此时可只传name参数,就能达到方法不同传参的同一个方法使用,约等于去掉self,这个方法实际参数只有一个name。如此理解就可以。

2.2.1 更深理解的例子辅助

class Student:
    # 类变量(相当于 Java 中的 static 变量)
    school_name = "Python大学"  
    
    def __init__(self, name, age):
        """
        构造函数
        self: 代表将来创建的实例本身
        name, age: 参数
        """
        # 实例变量(属性)- 每个实例都有自己的副本
        self.name = name    # self.name 是实例变量
        self.age = age      # self.age 是实例变量
        self.courses = []   # 创建一个空列表来存储课程
        
    def add_course(self, course):
        """
        实例方法
        self: 代表调用这个方法的实例
        course: 参数
        """
        self.courses.append(course)
        print(f"{self.name} 添加了课程: {course}")
    
    def show_info(self):
        """
        实例方法:显示学生信息
        """
        print(f"姓名: {self.name}")
        print(f"年龄: {self.age}")
        print(f"学校: {self.school_name}")
        print(f"课程: {', '.join(self.courses)}")
    
    @classmethod
    def change_school(cls, new_name):
        """
        类方法:修改学校名称
        cls: 代表类本身(而不是实例)
        """
        cls.school_name = new_name
        print(f"学校名称已改为: {new_name}")
    
    @staticmethod
    def school_motto():
        """
        静态方法:不需要访问类或实例的方法
        """
        return "好好学习,天天向上"

# 使用示例
if __name__ == "__main__":
    # 创建实例
    print("=== 创建学生实例 ===")
    student1 = Student("张三", 18)  # Python自动将实例传给self
    student2 = Student("李四", 19)
    
    # 调用实例方法
    print("\n=== 添加课程 ===")
    student1.add_course("Python基础")  # Python自动将student1传给self
    student1.add_course("数据结构")
    student2.add_course("算法导论")
    
    # 显示信息
    print("\n=== 显示学生1信息 ===")
    student1.show_info()
    print("\n=== 显示学生2信息 ===")
    student2.show_info()
    
    # 修改类变量
    print("\n=== 修改学校名称 ===")
    Student.change_school("新Python大学")
    
    # 再次显示信息
    print("\n=== 显示更新后的学生1信息 ===")
    student1.show_info()
    
    # 使用静态方法
    print("\n=== 显示校训 ===")
    print(Student.school_motto())
    
    # 展示实例的内部结构
    print("\n=== 实例的内部结构 ===")
    print(f"student1的属性字典: {student1.__dict__}")
    print(f"student2的属性字典: {student2.__dict__}")

2.2.2 学究式理解

这个例子展示了 Python 中类的几个重要概念:

  1. self 作用
    
    • self 代表实例本身
    • 当你创建 student1 = Student("张三", 18) 时,Python 自动将 student1 传给 self
    • 当你调用 student1.add_course("Python基础") 时,Python 自动将 student1 传给 self
  2. 不同类型的属性和方法:

    • 实例变量(通过 self 访问):每个实例独有
    • 类变量(所有实例共享):类似 Java 的 static 变量
    • 实例方法(带 self):需要访问实例属性的方法
    • 类方法(带 @classmethod):类似 Java 的 static 方法
    • 静态方法(带 @staticmethod):不需要访问实例或类的方法
  3. Python 的命名规范:

    • 类名用大写字母开头(如 Student
    • 变量和方法名用小写字母(如 name, add_course
    • 但这只是规范,不是强制的(与 Java 不同)

三、回归socket的self理解:①代表实例 ②可以把 self 理解为 Java 中的 this

def __init__(self):
    self.server_socket = socket.socket(...)

这里的含义是:

  1. self 代表将来创建的服务器实例
  2. self.server_socket 是给这个实例创建一个 socket 属性
  3. 每个服务器实例都有自己的 socket

当你创建服务器实例时:

server = SimpleTCPServer()  # Python 自动将 server 传给 self
server.start()  # Python 自动将 server 传给 self

你可以把 self 理解为 Java 中的 this,但在 Python 中需要显式写出来作为第一个参数。


http://www.kler.cn/a/371572.html

相关文章:

  • 快速遍历包含合并单元格的Word表格
  • Git 常用命令与开发流程总结
  • 使用 Microsoft Clarity 记录分析用户行为
  • Docker搭建基于Nextcloud的个人云盘/私有云盘/个人相册/家庭NAS
  • WPF:Binding数据绑定
  • 《使用Gin框架构建分布式应用》阅读笔记:p234-p250
  • 通过ssh端口反向通道建立并实现linux系统的xrdp以及web访问
  • 微服务设计模式 - 重试模式(Retry Pattern)
  • 驱动和芯片设计哪个难
  • Linux安装mysql【超详细】
  • 开放式耳机什么品牌最好?不入耳蓝牙耳机排行榜力荐!
  • 2016 年 7 月和 8 月期间进行的大气层析(ATom)-1 飞行活动中测得的黑碳(BC)质量混合比(单位:纳克 BC / 千克空气)
  • 【52 机器学习 | 基于KNN近邻和随机森林模型对用户转化进行分析与预测】
  • 1、两数之和
  • 油猴脚本-GPT问题导航侧边栏增强版
  • ip地址分为几大类-IP和子网掩码对照表
  • 【React】React 的核心设计思想
  • 经验总结:typescript 和 axios 项目中大量接口该如何管理和组织
  • 牛客算法简单题(JS版)
  • R语言在机器学习中的应用
  • unity中的材质(material)贴图(texture)着色器(shader)介绍
  • C++设计模式创建型模式———生成器模式
  • 【jvm】什么是TLAB
  • Ubuntu 22.04系统启动时自动运行ROS2节点
  • 【机器学习】Softmax 函数
  • GraphQL系列 - 第1讲 GraphQL语法入门