面向对象编程

一 对象的概念

程序 = 数据 + 功能

面向过程:

​ 核心是'过程'二字

​ 过程的终极奥义就是将程序流程化

​ 过程是'流水线',用来分步骤解决问题的

面向对象:

​ 核心是'对象'二字

​ 对象的终极奥义就是将程序"整合"

​ 对象是'容器',用来盛放数据与功能的

​ 示例:

​ 学生容器 = 学生的数据 + 学生的功能

​ 课程r容器 = 课程的数据 + 课程的功能

二 类与对象

1 类的概念

​ 类也是"容器",该容器用来存放同类对象共有的数据与功能

产生对象的类与对象之间存在关联,这种关联指的是:对象可以访问到类中共有的数据与功能,所以类中的内容仍然是属于对象的,类只不过是一种节省空间、减少代码冗余的机制,面向对象编程最终的核心仍然是是去使用对象。

类体代码,在类的定义阶段就运行了,产生类的名称空间(可以通过类.__ dict __ 查看)

写程序:先想哪些数据整合到一起。

在程序,必须事先定义好类,然后再调用类产生对象(调用类拿到的返回值就是对象)

注:类体代码是在类定义阶段就会立即执行,会产生类的名称空间

定义类

class Student:  #类的命名应该使用'驼峰体'
   	#1、变量的定义
    stu_school= 'oldboy'
   	# 空对象,'egon', 18, 'male'
  	def __init__(self, x, z):
      self.stu_name = x #空对象.stu_name = 'egon'
      self.stu_age = y #空对象.stu_age= 18
      self.stu_gender  = z #空对象.stu_gender = 'male'
   #2、功能的定义
  	def tell_stu_info(self):
      print('学生信息:名字:%s 年龄:%s 性别:%s' %(
            self.stu_name,
            self.stu_age,
            self.stu_gender
        ))
    def set_info(self,x,y,z):
        self.stu_name=x
        self.stu_age=y
        self.stu_gender=z

    def choose(self,x):
        print('正在选课')
        self.course=x

 	

​ 类是对象相似数据与功能的集合体,所以类体中最常见的是变量与函数的定义,但是类体其实可以包含任意其他代码的

可以通过 类. __ dict__ 来查看类这个容器内盛放的东西

如:

print(Student.__dict__)
#{..., 'stu_school': 'oldboy', 'choose': <function Student.choose at 0x128b6850>, ...}

2 对象

1、类实例化(调用类产生对象)

stu1_obj= Student('egon', 18, 'male')  #自动调用 __init__ 方法,Student.__init__(空对象,'egon',18,'male')
stu2_obj=Student('lili',19,'female')
stu3_obj=Student('jack',20,'male')

通过调用类产生的对象的名称空间(可以通过对象. __ dict __ 查看),调用类会自动触发类下面的__ init __ 方法

2、调用类的过程又称之为实例化,发生了三件事

1、先产生一个空对象(python 底层做了,是看不到的)

2、python 会自动调用类的__ init __ 方法,然后将空对象和已经调用类时括号内传入的参数一起传给 __ init __方法

3、返回初始完的对象

3、总结 __ init __ 方法

1、会在调用类时自动触发执行, 用来为对象初始化自己独有的数据

2、 __ init __ 内应该存放是为对象初始化属性的功能,但是是可以存放任意其他代码,想要在类调用时就立刻执行的代码都可以放到该方法内

3、__ init __方法必须返回 None(默认就是返回 None)

3、属性访问

1、类属性访问

在类中定义的名字,都是类的属性,类有两种属性:数据属性和函数属性,可以通过 __ dict __ 访问属性的值,比如 Student.__ dict __ ['stu _ school'], 但 python 提供了专门的属性访问语法

1、访问数据属性

print(Student.stu_school) #oldboy

2、访问函数属性

print(Student.tell_stu_info) #<function Student.tell_stu_info at 0x10fd4c1e0>
print(Student.set_info) #<function Student.set_info at 0x10fd4c378>

1)当通过类.方法来修改类的属性时,调用类的对象属性都会随之改变

Student.stu_school='OLDBOY'

print(stu1_obj.stu_school) #OLDBOY
print(stu2_obj.stu_school) #OLDBOY

2)当对象的属改变时,类的属性和其他调用该类的属性不会被改变

stu1_obj.stu_school='OLDBOY'

print(stu1_obj.stu_school) #OLDBOY
print(Student.stu_school)  #oldboy
print(stu2_obj.stu_school) # #oldboy
print(stu3_obj.stu_school) # #oldboy

原因就是类中定义的函数主要是给对象使用的,而且是绑定给对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法,内存地址各不相同。

3)类调用自己的函数属性必须严格按照函数的用法来(有几个参数就必须传几个)

#类实例化产生对象
stu1_obj= Student('egon', 18, 'male')  #自动调用 __init__ 方法,Student.__init__(空对象,'egon',18,'male')
stu2_obj=Student('lili',19,'female')
stu3_obj=Student('jack',20,'male')

#通过类调用方法
Student.tell_stu_info(stu1_obj) #学生信息:名字:egon 年龄:18 性别:male
Student.tell_stu_info(stu2_obj) #学生信息:名字:lili 年龄:19 性别:female
Student.tell_stu_info(stu3_obj) #学生信息:名字:jack 年龄:20 性别:male

2、对象属性访问

类通过实例化产生对象,这时对象就有了对象的绑定方法,绑定方法的特殊之处在于:谁(对象)来调用绑定方法就会将谁当做第一个参数传入

#类实例化产生对象
stu1_obj= Student('egon', 18, 'male')  #自动调用 __init__ 方法,Student.__init__(空对象,'egon',18,'male')
stu2_obj=Student('lili',19,'female')
stu3_obj=Student('jack',20,'male')

stu1_obj.tell_stu_info() #tell_stu_info(stu1_obj) #学生信息:名字:egon 年龄:18 性别:male
stu2_obj.tell_stu_info() #tell_stu_info(stu2_obj)
stu3_obj.tell_stu_info() #tell_stu_info(stu3_obj)

3、操作对象的属性

print(stu1_obj.__dict__) #{'stu_name': 'egon', 'stu_age': 18, 'stu_gender': 'male'}


#查看
stu1_obj.stu_name #egon 等同于 stu1_obj.__dict__['stu_name']

#新增
stu1_obj.stu_hobby = 'play basketball'
print(stu1_obj.__dict__) #{'stu_name': 'egon', 'stu_age': 18, 'stu_gender': 'male'}

#修改
stu1_obj.stu_gender = 'female'
print(stu1_obj.__dict__) #{'stu_name': 'egon', 'stu_age': 18, 'stu_gender': 'female', 'stu_hobby': 'play basketball'}

#删除
del stu1_obj.stu_hobby
print(stu1_obj.__dict__) #{'stu_name': 'egon', 'stu_age': 18, 'stu_gender': 'female'}

4、属性查找顺序与绑定方法

对象的名称空间里只存放着对象独有的属性,而对象相似的属性是存放于类中的。对象在访问属性时,会优先从对象本身的__ dict __ 中查找,未找到,则取类中的__ dict __ 中查找

类的属性是共享给所有对象用,所以大家访问的地址都是一样的

print(id(stu1_obj.stu_school)) # #4494520136
print(id(stu2_obj.stu_school)) # #4494520136
print(id(stu3_obj.stu_school)) # #4494520136

绑定到对象的方法特殊之处在于,绑定给谁就应该由谁来调用,谁来调用,就会将’谁’本身当做第一个参数自动传入(方法__ init __也是一样的道理),在使用对象的绑定方法时,python 会默认将对象本身当做第一个参数自动传入,因此无需我们再传入。

绑定到不同对象的 choose 技能,虽然都是选课,但是学生 1 选的课不会选给学生 2,这正是'绑定'二字的精髓所在

stu1_obj.choose('python全栈开发')
print(stu1_obj.course)

stu2_obj.choose('linux运维')
print(stu2_obj.course)

stu3_obj.choose('高级架构师')
print(stu3_obj.course)

注:绑定到对象方法的这种自动传值特征,决定了在类中定义的函数都要默认写一个参数 self,self 可以是任意的名字,但是命名为 self 是约定俗成的

python 中一切皆为对象,且 python3中类与类型是一个概念

#类型list就是类
>>> list
<class 'list'>

#实例化得到 3个对象l1,l2,l3
>>> l1=list([1,2,3])
>>> l2=list(['a','b','c'])
>>> l3=list(['x','y'])

#三个对象都有绑定方法append,是相同的功能,但内存地址不同
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8>

#操作绑定方法l1.append(4),就是在往l1添加4,绝对不会将4添加到l2或l3
>>> l1.append(4) #等同于list.append(l1,4)
>>> l1
[1,2,3,4]
>>> l2
['a','b','c']
>>> l3
['x','y']
原文地址:https://www.cnblogs.com/xy-han/p/12656351.html