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 作用
      
    2. self 代表实例本身
    3. 当你创建 student1 = Student("张三", 18) 时,Python 自动将 student1 传给 self
    4. 当你调用 student1.add_course("Python基础") 时,Python 自动将 student1 传给 self
    5. 不同类型的属性和方法:

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

    12. 类名用大写字母开头(如 Student
    13. 变量和方法名用小写字母(如 name, add_course
    14. 但这只是规范,不是强制的(与 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 中需要显式写出来作为第一个参数。

    作者:姜姜姜姜名字都有

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python基础:python的self是啥 附:含数据接收、解码和保存例子(基础)

    发表回复