对Python中class和instance以及self的用法详解
作者:Hansry 发布时间:2022-09-08 23:28:14
一. Python 的类和实例
在面向对象中,最重要的概念就是类(class)和实例(instance),类是抽象的模板,而实例是根据类创建出来的一个个具体的 “对象”。
就好比,学生是个较为抽象的概念,同时拥有很多属性,可以用一个 Student 类来描述,类中可定义学生的分数、身高等属性,但是没有具体的数值。而实例是类创建的一个个具体的对象, 每一个对象都从类中继承有相同的方法,但是属性值可能不同,如创建一个实例叫 hansry 的学生,其分数为 93,身高为 176,则这个实例拥有具体的数值。
1.类:以Student类为例,在Python中,定义类如下:
class Student(object):
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类,我们只知道创建实例需要给出 name 和 score。究竟如何打印,是 Student 类内部定义的,这些数据和逻辑被封装起来了,调用也就变得容易了,但是不知道内部实现的细节。
如果不想让实例中的内部属性被外部属性访问,则把 name 和 score 变成 __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 实例化时生成的。
来源:https://blog.csdn.net/Hansry/article/details/79639676


猜你喜欢
- JavaScript简介一、定义:JavaScript是脚本语言,需要宿主文件,它的宿主文件是html文件。JavaScript 是一种轻量
- 一个post类型的接口怎么编写脚本实现1、打开网页,在fiddler上获取到接口的URL2、用Python的requests库实现impor
- 只是做笔记,没什么!! --创建测试表 CREATE TABLE [dbo].[Student]( [ID] [int] IDENTITY(
- 目录关于Web服务器和应用服务器Python项目部署架构关于cgi、wsgi、uwsgi、http协议关于cgi、fastcgi、php-f
- 相信每个前端工程师都有自己喜爱的javascript框架,说情感也好,道信仰也罢,javascript框架带给人的不仅仅是便捷的开发,更有一
- 开始一个组件,毫无目的的写代码是一个不好的习惯,要经历 分析 => 抽象 => 实现 => 应用 四个阶段。组件DEMO地
- 原因是:It looks like you need to flush stdout periodically (e.g. sys.stdo
- 使用matplotlib创建百分比堆积柱状图的思路与堆积柱状图类似,只不过bottom参数累计的不是数值而是百分比,因此,需要事先计算每组柱
- /* 建立数据表 */ create table td_base_data( id int(10) not null auto_increm
- 经常有网友会问,SQL Server占用了太多的内存,而且还会不断的增长;或者说已经设置了使用内存,可它没有用到那么多,这是怎么一回事儿呢?
- 如果不用类库(如jquery)来写,往往很多时候,都需要通过id或tag来获取html里的某一对象,然后对其进行操作。为了节省代码,把常用的
- 本文详细分析了Yii框架的登录流程。分享给大家供大家参考。具体分析如下:Yii对于新手来说上手有点难度,特别是关于session,cooki
- 写在前面现在人人都有微信,一句“咱们加个微信呗”搭载了你我之间的友谊桥梁,浑然不知自己的微信朋友已经四五百了,甚至上千,几千的都有;然而那个
- 简介在各个语言之中都有时间类型的处理,因为这个地球是圆的(我仿佛在讲废话),有多个时区,每个时区的时间不一样,在程序中有必要存在一种方式,或
- 以下测试用于去除任何字符串中连线的分隔符 --去除字符串中连续的分隔符 declare @str nvarchar(200) declare
- 我们在浏览网页的时候偶尔会遇到一些陌生的网页交互行为,通常情况下它们并不会影响你的正常使用,之所以出现情况往往是因为,设计师在设计某个交互方
- 执行以下SQL,即OK咯叻!! SQL:alter database 数据库名称 SQL_Latin1_General_CP1_CI_AS
- 本文实例讲述了PHP实现的AES双向加密解密功能。分享给大家供大家参考,具体如下:<?php/* * Created on 2018-
- list解析先看下面的例子,这个例子是想得到1到9的每个整数的平方,并且将结果放在list中打印出来>>> power2
- 首先,看看本文所面向的应用场景:我们有一个数据集df,现在想统计数据中某一列每个元素的出现次数。这个在我们前面文章《如何画直方图》中已经介绍