Python 中 class 和 instance 以及 self 的用法

本文介绍了Python面向对象编程的基础知识,包括类和实例的概念、创建及使用方法,如何封装类的属性并通过方法进行访问和修改,以及self参数的具体作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. Python 的类和实例

在面向对象中,最重要的概念就是类(class)和实例(instance),类是抽象的模板,而实例是根据类创建出来的一个个具体的 “对象”。
就好比,学生是个较为抽象的概念,同时拥有很多属性,可以用一个 Student 类来描述,类中可定义学生的分数、身高等属性,但是没有具体的数值。而实例是类创建的一个个具体的对象, 每一个对象都从类中继承有相同的方法,但是属性值可能不同,如创建一个实例叫 hansry 的学生,其分数为 93,身高为 176,则这个实例拥有具体的数值。

1.类:以Student类为例,在Python中,定义类如下:

class Studentobject):
    def __init__(self,name,score):
        self.name=name
        self.score=score

a.(object)表示的是该类从哪个类继承下来的,而object类是每个类都会继承的一个类。 yt
b. __init__ 方法的第一参数永远是 self,用来表示类创建的实例本身,因此,在 __init__ 方法内部,就可以把各种属性绑定到self,因为self 本身就是指向创建的实例本身。
c. 有了 __init__ 方法后,在创建实例的时候,就不能传入空参数,必须传入与 __init__ 方法匹配的参数,但self本身不需要传入参数,只需要传入 self 后面的参数即可。

2.实例: 定义好了类后,就可以通过Student类创建出 Student 的实例,创建实例是通过 类名 + ()实现:

student = Student('name', 93>>> student.name
"name"
>>> student.score
93

a. 其中 Student 是类名称,(’name’,93)为要传入的参数
b. self.name 就是 Student类的属性变量,为 Student 类所有。同时, name 是外部传来的参数,不是 Student 类所自带的。故 self.name = name 的意思就是把外部传来的参数 name 的值赋值给 Student类自己的属性变量 self.name .

3.和普通函数相比,在类中定义函数只有一点不同,就是第一参数永远是类的本身实例变量 self, 并且调用时,不用传递该参数。 除此之外,类的方法(函数)和普通函数没有啥区别。既可以用 默认参数、可变参数或者关键字参数等。

二. 类 以及 实例的访问

1.限制外部对类实例属性的访问

既然 Student 类实例本身就拥有这些属性的数据,那么要访问这些数据,就没必要从外面的函数去访问,而可以在类的内部定义访问数据的函数,这样,就可以把 ”数据“ 封装起来了。这些封装数据的函数和 Student 类本身是相关联的,称之为类的方法:

class Student(obiect):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print "%s: %d" % (self.name, self.score)
>>> student= Student("hansry",99)
>>> student.print_property()

hansry:99

由此可见,从外部看Student类,我们只知道创建实例需要给出 namescore。究竟如何打印,是 Student 类内部定义的,这些数据和逻辑被封装起来了,调用也就变得容易了,但是不知道内部实现的细节。

如果不想让实例中的内部属性被外部属性访问,则把 namescore 变成 __name__score 即可,如下代码所示:

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score
    def print_property(self):
        print "%s: %d" %(self.__name,self.__score)
>>> student= Student("hansry",99)
>>> student.print_property()
>>> student.__name()

hansry:99
Traceback (most recent call last):
AttributeError: 'Student' object has no attribute '__name'

2.开 API 使得外部代码能够访问到里面的属性,并且对其进行修改

外部代码访问到类实例属性,代码如下:

    def __init__(self,name,score):
        self.__name=name
        self.__score=score
    def print_property(self):
        print("%s:%d"%(self.__name,self.__score))

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score 
name=student.get_name()
score=student.get_score()
print ("%s%d" % (name,score))

外部代码修改类里面的实例属性,代码如下:

    def __init__(self,name,score):
        self.__name=name
        self.__score=score
    def print_property(self):
        print("%s:%d"%(self.__name,self.__score))

    def reset_name(self,change_name):
        self.__name = change_name

    def reset_score(self, change_score):
        self.__score = change_score 
student= Student("hansry",99)
student.print_property()
student.reset_name("simona")
student.reset_score(91)
name=student.get_name()
score=student.get_score()
print ("%s:%d" % (name,score))

hansry:99
simona:91

需要注意的是,在Python中,变量名类似 _xxx_的,也就是双下划线开头,并且以下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是 private 变量,不能用 __name__, __score__

三. self 的仔细用法

1.self代表类的实例,而非类。

class Student(object):
    def print_self(self):
        print(self)
        print(self.__class__)
student=Student()
student.print_self()

<__main__.Student object at 0x7fd9095aed90>
<class '__main__.Student'>

从上面例子可得,self代表的只是类的实例,而 self.__class__ 才是类。

2. 定义类的时候,self最好写上,因为它代表了类的实例。
3. 在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。

class Teacher(object):
    def __init__(self,teacher):
        self.teacher=teacher
        print(self.teacher)

    def print_self(self):
        print(self)

class Student(Teacher):
    def __init__(self,student):
        self.student=student        
        print(self.student)

    def print_self_1(self):
        print(self)
teacher=Teacher("hansry")
student=Student("simona")
student.print_self_1()
student.print_self()

hansry
simona
<__main__.Student object at 0x7fd9095b0950>
<__main__.Student object at 0x7fd9095b0950>

在运行 student.print_self() 的时候,这里是调用了 类 Teacher 的 print_self() 函数,此时虽然调用的是 类Teacher的函数,但是此时的实例 self 确是 类 Student 实例化时生成的。

参考:http://blog.csdn.net/CLHugh/article/details/75000104

<think>嗯,我现在要理解Python类中的self是什么意思。刚开始学Python的时候,看到类里面的方法都有一个self参数,但调用的时候又不用传,觉得有点奇怪。那这个self到底是什么呢? 首先,可能self代表的是类的实例本身。比如,当我创建一个类的实例,比如my_object = MyClass(),然后调用my_object.method()的时候,实际上method的第一个参数就是self,也就是这个实例。那为什么在方法定义的时候需要显式地写出self呢?而调用的时候却不需要传这个参数? 然后,我记得在其他的编程语言,比如Java或者C++中,类的成员方法不需要显式地声明这个参数,而是用this关键字来引用当前对象。Python的做法可能类似,但需要显式地将self作为第一个参数,这样在方法内部就可以访问实例的属性其他方法了。 那如果不加self会怎么样?比如,定义一个方法的时候忘了写self参数,这时候调用这个方法会不会出错?比如,写了一个类: class MyClass: def my_method(): print("Hello") 然后实例化后调用my_instance.my_method(),这时候应该会报错,提示缺少参数,因为Python会自动把实例作为第一个参数传递,但方法定义的时候没有参数,所以参数不匹配。这可能就是为什么必须在方法定义中加上self的原因。 那self这个名称是强制的吗?比如,我能不能用别的名字,比如this或者其他的?好像是可以的,因为Python只是把第一个参数当作实例的引用,不管叫什么名字。比如: class MyClass: def method(this): this.value = 10 这样写应该也是可以的,但按照惯例,大家都用self,所以最好还是遵循这个约定,保持代码的可读性。 接下来,self在类的方法中是如何使用的?比如,在__init__方法中,初始化实例属性的时候,就需要用self.attribute = value。这样每个实例都会有自己的一套属性,互不干扰。如果不用self的话,定义的变量可能属于方法内的局部变量,或者如果是类变量的话,会被所有实例共享。 比如,在类的方法中: def set_value(self, value): self.value = value 这样每个实例调用set_value的时候,就会给该实例的value属性赋值。而如果方法内部没有使用self,直接value = something,那这个变量可能只是方法的局部变量,实例并不会保存这个值。 还有,类方法(@classmethod)静态方法(@staticmethod)中的self有什么不同?类方法的第一个参数通常是cls,代表类本身,而静态方法不需要参数,因为它们不需要访问实例或类的属性。这可能是另一个需要注意的点。 总结一下,selfPython类中是一个指向实例本身的引用,通过它,实例可以访问自己的属性方法。虽然在语法上可以用其他名称代替self,但按照约定应该使用self,这样代码更易读。此外,在定义实例方法时必须显式地将self作为第一个参数,而在调用时不需要传递,由Python自动处理。</think>在 Python 的类中,`self` 是一个指向类**实例自身**的引用参数,它用于访问实例的属性方法。以下是关键点: ### 1. **`self` 的作用** - **实例标识**:`self` 代表类的当前实例(对象),类似于其他语言中的 `this`。 - **访问属性方法**:通过 `self.属性名` 或 `self.方法名()` 访问实例的数据功能。 ### 2. **为何需要显式声明?** - Python 要求将 `self` 作为实例方法的第一个参数,但调用时无需手动传递(Python 自动处理)。 - 例如: ```python class Dog: def __init__(self, name): self.name = name # 实例属性 def bark(self): print(f"{self.name}在叫!") # 通过self访问属性 my_dog = Dog("旺财") my_dog.bark() # 输出:旺财在叫! ``` 调用 `my_dog.bark()` 时,Python 自动将 `my_dog` 作为 `self` 传入。 ### 3. **常见误区** - **忘记写 `self`**:若方法未将 `self` 作为第一个参数,调用时会报错(参数不匹配)。 - **命名非强制但建议**:可用其他名称(如 `this`),但强烈建议遵循惯例使用 `self` 以提高可读性。 ### 4. **与其他方法的对比** - **类方法(`@classmethod`)**:首个参数是 `cls`,指向类本身(而非实例)。 - **静态方法(`@staticmethod`)**:无需 `self` 或 `cls`,与普通函数类似。 ### 示例代码 ```python class MyClass: def __init__(self, value): self.value = value # 实例属性 def print_value(self): print(self.value) # 通过self访问实例属性 obj = MyClass(10) obj.print_value() # 输出:10 ``` ### 总结 - `self` 是实例方法的“第一个参数”,用于操作实例的属性行为。 - Python 隐式传递 `self`,开发者只需在定义时声明,调用时无需处理。 - 遵循 `self` 命名约定,避免混淆代码逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值