self关键字

一、self 是什么?(定义)

self 是 Python 类中实例方法第一个参数,代表当前正在调用该方法的实例对象本身

注意:self 只是约定俗成的名字,你可以用 thisme 等其他名字代替,但强烈不推荐,会破坏代码可读性。

二、self 的核心作用

1. 访问实例属性和方法

通过 self.属性名self.方法名(),在类内部访问当前实例的属性和方法。

2. 区分实例变量和局部变量

当方法内的局部变量名与实例变量名相同时,self 能明确区分「实例变量」和「局部变量」。

三、self 的工作原理(面试常考)

Python 解释器会自动将「调用方法的实例对象」作为第一个参数传递给 self,无需手动传入。

例子说明
class Person:
    def say_hello(self):
        print(f"Hello, 我是 {self.name}")

# 创建实例
p = Person()
p.name = "Tom"

# 调用方法:Python 自动将 p 传给 self
p.say_hello()  # 等价于 Person.say_hello(p)
  • 调用 p.say_hello() 时,Python 实际执行的是 Person.say_hello(p),将实例 p 作为第一个参数传给 self

四、常见例子

class Person:
    def __init__(self, name, age):
        # self.name:实例变量;name:局部变量(参数)
        self.name = name  # 将参数值赋给实例变量
        self.age = age

    def introduce(self):
        # 通过 self 访问实例变量
        print(f"我叫 {self.name},今年 {self.age} 岁")

# 使用
p = Person("Tom", 18)
p.introduce()  # 输出:我叫 Tom,今年 18 岁

五、常见误区(面试常踩坑)

1. 忘记写 self
# 错误写法:实例方法必须有 self 参数
class Person:
    def say_hello():  # 缺少 self
        print("Hello")

p = Person()
p.say_hello()  # 报错:TypeError: say_hello() takes 0 positional arguments but 1 was given
2. 在类方法 / 静态方法中用 self
  • 类方法:第一个参数是 cls(代表类本身),不是 self
  • 静态方法:没有默认的第一个参数,不能用 self
class Person:
    # 类方法:用 cls
    @classmethod
    def class_method(cls):
        print(f"这是类方法,类名是 {cls.__name__}")

    # 静态方法:无默认参数
    @staticmethod
    def static_method():
        print("这是静态方法")

面试总结

  • self 是实例方法的第一个参数,代表当前调用方法的实例对象
  • 作用是访问实例属性和方法,区分实例变量和局部变量;
  • Python 会自动将实例传给 self,无需手动传入;
  • 类方法用 cls,静态方法不用 self

*args和**kwargs

一、定义与作用

*args**kwargs 是 Python 的语法糖,用于让函数 / 方法接收任意数量的参数,名字是约定俗成的(可换为 *vars**kw 等,但强烈不推荐):

语法 作用 打包后的数据类型
*args 接收任意数量的位置参数(Positional Arguments) 元组(tuple)
**kwargs 接收任意数量的关键字参数(Keyword Arguments,即 key=value 形式) 字典(dict)

二、基本用法

1. *args:接收任意位置参数
def add(*args):
    # args 是元组,可直接遍历
    return sum(args)

print(add(1, 2))          # 输出 3
print(add(1, 2, 3, 4))    # 输出 10
print(add())               # 输出 0(空元组)
2. **kwargs:接收任意关键字参数
def print_info(**kwargs):
    # kwargs 是字典,可直接遍历键值对
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Tom", age=18)
# 输出:
# name: Tom
# age: 18

print_info(city="杭州", job="工程师", hobby="编程")
# 输出:
# city: 杭州
# job: 工程师
# hobby: 编程

三、组合使用:固定参数 + *args + **kwargs(核心考点)

当同时使用时,参数顺序必须严格遵循

固定参数 → *args → **kwargs
例子
def func(a, b, *args, **kwargs):
    print(f"固定参数:a={a}, b={b}")
    print(f"*args 位置参数:{args}")
    print(f"**kwargs 关键字参数:{kwargs}")

func(1, 2, 3, 4, name="Tom", age=18)
# 输出:
# 固定参数:a=1, b=2
# *args 位置参数:(3, 4)
# **kwargs 关键字参数:{'name': 'Tom', 'age': 18}

四、进阶用法:解包(Unpacking)

*** 不仅能打包参数,还能解包可迭代对象 / 字典,将其作为参数传给函数:

1. * 解包可迭代对象(列表、元组、字符串等)
def add(a, b, c):
    return a + b + c

my_list = [1, 2, 3]
print(add(*my_list))  # 等价于 add(1, 2, 3),输出 6

my_tuple = (4, 5, 6)
print(add(*my_tuple)) # 等价于 add(4, 5, 6),输出 15
2. ** 解包字典
def print_info(name, age):
    print(f"name: {name}, age: {age}")

my_dict = {"name": "Tom", "age": 18}
print_info(**my_dict) # 等价于 print_info(name="Tom", age=18)

五、常见误区(面试常踩坑)

  1. 参数顺序错误:必须遵循「固定参数 → *args → **kwargs」,否则会报错;
  2. 名字不是必须的*args 可换为 *vars**kwargs 可换为 **kw,但约定俗成的名字更易读;
  3. 仅限关键字参数* 后的参数必须用关键字传入(如 def func(a, *, b),调用时必须 func(1, b=2))。

面试总结

  • *args 接收任意位置参数,打包成元组;
  • **kwargs 接收任意关键字参数,打包成字典;
  • 组合使用时严格遵循参数顺序;
  • 可通过 */** 解包可迭代对象 / 字典传参。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐