带你了解Python面向对象 (1) 基础篇:类与对象、初始化对象属性

目录

  • 前言:
  • 面向对象编程(OOP)
    • 类与对象
    • 对象绑定方法
    • 定义对象的属性
    • 初始化属性
    • 类与数据类型
    • 面向对象基础小结


前言:

我们编程可分为两种编程思想:

面向过程:将程序进行流程化,即把程序的步骤整理清楚再一步步实现,但是拓展性差,程序的流程在写程序的时候已经决定好,后期更改程序会牵扯到有关联性的一些功能。
理解:面向过程关注的是解决问题需要哪些步骤


面向对象:将程序的变量以及功能整合到一起成为:对象,程序的流程是在对象生成后决定的,后期拓展程序只需要更改对象(或实例化对象的类)即可
理解:面向对象关注的是解决问题需要哪些对象

但并不是说开发程序一定只用面向对象编程思想来进行开发,选取对我们更有优势的方式才是最好的!那么本篇就来介绍一下面向对象编程~

本篇主要介绍面向对象的基础内容


面向对象编程(OOP)

Python作为设计之初就是作为一种面向对象的编程语言。

什么是对象?目前可以理解为:有名称、属性、功能的集合体

其实在我们平常所使用python时就已经接触到对象

拿定义一个变量来举例:所列出的方法是x这个字符所具备的吗?
带你了解Python面向对象 (1) 基础篇:类与对象、初始化对象属性_第1张图片
并不是,我们可以看成:x = int(10) 这样更利于理解,因为我们输入10,Python会检测到我们输入的内容进而帮我们转换为对应的数据类型。可以理解成:10是由int产生的,之后我们将10赋给一个变量,这个变量此时就可以称之为:对象

那么我们来说一下如何产生对象。

类与对象

上序所说的int就是一个类名,Python中对象是由调用类而实例化出的

类的定义:由class关键字产生

class 类名:
	<statement...>

那么我们获取对象则是调用定义的类名

class Person: # 类名的定义推荐采用驼峰体:即单词的首字母大写
	age = 10 # 类的属性

	def f(self):
		print('Hello class')

p = Person() # 那么我们通过调用Person这个类,实例化出一个名为:p的对象
print(p.age) # 访问这个类的属性
p.f() # 访问这个类的方法

我们会注意到:在类里面def创建函数时,会自动产生一个self的参数。这个待往下了解会提到,暂时不用在意

在定义类后,会产生一个名称空间,我们可以通过类名.__dict__来进行查看

print(Person.__dict__)
{
      '__module__': '__main__', 'age': 10, 'f': <function Person.f at 0x7fc95eb9edc0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

# 可以看到一堆这样字典内容,__开头的我们不需要关注,这里看到age它是我们定义的一个类属性

对象也具备__dict__可以查看其名称空间

p = Person()
print(p.__dict__)
{
      }

我们可以看到p这个对象,名称空间内并无任何内容,仔细观察上面调用时可以发现,我们调用的是类的属性,并不是自己的,这就涉及到一个查找属性的优先级:

对象查找属性:优先查找自身是否具备这个属性,如果不具备则到对应的类中去查找,再未找到则报错,我们目前了解到这里即可,后续会涉及到继承查找


对象绑定方法

接着来把上序类里面方法有个一个参数名为self

因为类里面的属性以及函数都是提供给对象使用的,而如果类本身来调用它就与普通函数无异了,该传递几个参数就传递几个。所以我们着重解释self的作用

拿例子比喻:

class Person:
	age = 10

	def f(self):
		print('Hello class')

p = Person()
p.f() # 访问这个类的方法

它的作用就是,我们这个p对象在调用类时,就会将类里面的f方法 绑定给p对象,在调用这个f方法时,会自动将与之绑定的对象传递进去,当然参数也可以不是self,但是在Python中约定通常使用self字符作为参数

self(自己):这里也可以理解为,调用这个方法的对象

类里面的方法是共享给所有对象的,谁来调用它,它就与之进行绑定,我们在这个方法里面就可以获取绑定对象的属性

class Person:
	age = 10

	def f(self):
		print('Hello class')

p1 = Person()
p2 = Person()
print(Person.f)
print(p1.f)
print(p2.f)

执行结果

<function Person.f at 0x7f8059a9edc0>
<bound method Person.f of <__main__.Person object at 0x7f8059a6dfd0>>
<bound method Person.f of <__main__.Person object at 0x7f8059a6de80>>

# 可以看到,通过类调用里面的函数它就只是普通函数
# 我们通过对象调用它就成了方法,虽说方法只有一个,但是每次传递进去的对象都是不同的
# 所以产生的效果也不同,self准确来说就是接收传递进来的对象

定义对象的属性

给对象添加一些属性,而不是去类里面拿,访问这个对象自身就能拿到值

# 和上序一样的内容,我们做点手脚!
class Person:
	age = 10
	def f(self):
		print('Hello class')

p = Person()
p.age = 1
print(p.age)
# 此时我们打印出来的内容就是这个p对象本身的age属性值,而不是去类里面查找属性
>>> 1

就是说,当我们对象自身拥有这个属性时,就不会跑到类里面去找!
再来绕一下,看看是否了解:根据下列代码说出打印内容

p1 = Person()
p1.age += 1

p2 = Person()

print(p1.age)
print(p2.age)

p1.age的执行为:先在p1这个对象里面查找,发现没有,再去类里面查找,找到内容以后+1后,将age这个属性赋给p1这个对象。p1具备了age这个属性,值为:11。
而p2.age没有在自身这个对象找到,则去类里面找到,打印出来


初始化属性

在调用类的过程中将我们需要的属性就给定义好,实例化对象后,直接调用这个属性即可。

类里面具备一个__init__方法,注意:是init ,因为类里面同样有一个极其相似的方法,就是int,不一样的方法,实现的效果不同,切记!

定义方法:

class Person:
	def __init__(self):
		给对象初始化的属性

使用方式:在__init__里面接收我们在调用类时传递进来的参数再赋给对象

class Person:
	def __init__(self,name,age): # 在调用类时,自动触发这个方法的运行
		self.name = name
		self.age = age

p = Person('jack',18)
print(p.name)
print(p.age)

执行效果:可以看到p对象已经拥有自己的属性

jack
18

经过了解绑定方法以后,我们可以知道,上序self可以代表p对象,而self.name = name则是给p对象添加一个name属性而属性值则是我们调用类时传递进去的。

在类里面调用方法需要携带self

class Person:
    def f1(self):
        print('f1')

    def f2(self):
        self.f1()
        print('f2')

p = Person()
p.f2()

执行结果

'f1'
'f2'

类与数据类型

这是我们可以再来看平常所定义的列表

l = [1,2,3,4,5] # 平常都是这样定义的,那么我们可以这样
# l = list([1,2,3,4,5]) 其实就是经过了list这个类而产生的,只不过我们平时不会这样写,因为Python会帮我们转换
# 那么这个l就属于一个对象了,因为它是经历过调用类而实例化出的,所以它也有一些方法

l对象的方法都是由list这个类提供的,因为它本身就是由list类产生的
带你了解Python面向对象 (1) 基础篇:类与对象、初始化对象属性_第2张图片
那么再来与我们上序讲到的对象绑定方法结合就能理解,定义两个列表(对象)

l1 = [1,2,3,4,5]
l2 = [5,4,3,2,1]

l1.append(6)
l2.append(0)

那我们调l1对象里面的方法与l2对象无关吧?因为它们都是实例化出的对象,每一个都是独立的,哪个对象调用append()这个方法也只是将这个对象传递进去,第二步再将我们需要给这个对象属性增加的值传递进去。
在这里插入图片描述
可以看到,也是由self参数接收了我们调用这个方法的对象,再是跟传递进来内容,只是由于这是个内置类(或C语言写的进行过编译)方法,所以看不到源码,也不用在意

原理就是

l = [1,2,3,4,5]
l.append(6) # 等同于 list.append(l,6) 第一个是对象,第二个是值

# 可以明白,第一个是传入的对象,第二个才是传入的值,那么我们就可以调用list这个类给l对象追加值
list.append(l,7)

print(l)

打印结果

[1, 2, 3, 4, 5, 6, 7]

重点:

在前面我们经常使用type()来查看我们变量值的属性,其实在学习面向对象以后可以得知,它反馈的只是我们这个变量值是由哪个类而产生的

l = [1,2,3,4,5]
print(type(l))

打印结果

<class 'list'>

Python统一了类与类型的概念:类就是类型


面向对象基础小结

面向对象并不会使代码有所减少,但是更利于调用与拓展,我们可以通过几个练习来观察面向过程与面向对象之间的区别。

链接中存在3个源码文件:

有两个爬取梨视频网页的源码,实现效果一直,但所写方法不同。
有一个使用面向对象来模拟王者荣耀英雄对战的源码文件。

百度网盘:https://pan.baidu.com/s/13jM3eNwhASAB20wONuKCVg?errmsg=Auth+Login+Sucess&errno=0&ssnerror=0&#list/path=%2F&parentPath=%2F
提取码:mwql

有兴趣可以尝试写一下!!有助于巩固面向对象的基础内容


下一章 进阶篇:https://blog.csdn.net/m0_46958731/article/details/111603575


技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点赞 收藏+关注 子夜欢迎您的关注,谢谢支持!

你可能感兴趣的:(Python面向对象,Python进阶,python,面向对象编程)