self关键字
一、self 是什么?(定义)
self是 Python 类中实例方法的第一个参数,代表当前正在调用该方法的实例对象本身。
注意:
self只是约定俗成的名字,你可以用this、me等其他名字代替,但强烈不推荐,会破坏代码可读性。
二、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 given2. 在类方法 / 静态方法中用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),输出 152.**解包字典
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)五、常见误区(面试常踩坑)
- 参数顺序错误:必须遵循「固定参数 → *args → **kwargs」,否则会报错;
- 名字不是必须的:
*args可换为*vars,**kwargs可换为**kw,但约定俗成的名字更易读; - 仅限关键字参数:
*后的参数必须用关键字传入(如def func(a, *, b),调用时必须func(1, b=2))。
面试总结
*args接收任意位置参数,打包成元组;**kwargs接收任意关键字参数,打包成字典;- 组合使用时严格遵循参数顺序;
- 可通过
*/**解包可迭代对象 / 字典传参。