Python基础系列(五)类和对象,让你更懂你的python代码

首先,非常感谢各位打开本博文,本博文是Python入门基础系列文章之一,Python目前是非常火的编程工具,其实作为编程不在只是程序员的专利,每一个人在日常的工作中、学习中都会或多或少的要用到一些工具去帮助我们解决问题,那么Python将会是一个非常合适的工具之一。
笔者认为,python已经类似office一样,成为了我们日常办公中的重要工具。
作为Python入门基础系列文章,共包含六篇,具体文章如下:

  1. 好的开始,是成功的起点。(python+pycharm+print+pip+快捷键)
  2. 基础概念,进入python的第一课!(基本类型认知、互转)
  3. 文件操作,让python与外界互联互通!(os)
  4. 多线程处理,python的一把利器!(thread)
  5. 类和对象,让你更懂你的python代码!(class)
  6. Debug代码跟踪和try-except异常捕获,排错的万能助手!(DEBUG)

千里之行,始于足下,让我们一起在python的世界里分享、学习、共同进步吧!
好的,下面让我们正式进入本章:类和对象,让你更懂你的python代码(class)
本章节的内容包括:

Python认为一切皆为对象。
我们一直使用的数据类型,其实本身就是python内置的一个类,我们在使用的过程中,就是在实例化这个类的对象,形成一个个我们需要用到的数据类型和数据。以list类为例:

li = list('abc')
print(li)
print(li.__class__)
print(li.__class__.__name__)

运行的结果如下:

['a', 'b', 'c']
<class 'list'>
list

我们自己也可以自定义类和对象,那么如何理解面向对象呢?

面向对象(OOP)是一种对现实世界理解和抽象的方法,对象的含义是指在现实生活中能够看得见摸得着的具体事物,面向对象编程简单来说就是一种封装代码的方式。

一、面向对象的基本概念

(一)Python对象特性

python使用对象模型来存储数据。构造任何类型的值都是一个对象。所有python对象都拥有三个特性:身份、类型、值:
1)身份:每个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数 id() 来得到。
2)类型:对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。可以使用 type() 函数查看python对象的类型。type()返回的是对象而不是简单的字符串。
3):对象表示的数据。

(二)面向对象相关概念

类:描述具有相同属性和方法的集合,简单来说就是一个模板,通它来创建对象。
对象:类的实例。
方法:类中定义的函数。
类变量:定义在类中且在函数之外的变量,在所有实例化对象中公用。

(三)面向对象三大特性

封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,提高复用性和安全性。
继承:一个类继承一个基类便可拥有基类的属性和方法,可提高代码的复用性。
多态:父类定义的引用变量可以指向子类的实例对象,提高了程序的拓展性。

简言之,类(Class)用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法,而对象就是类的实例。

二、用函数来定义方法

函数就是一段实现特定功能的代码,使用函数可以提高代码的重复利用率,当为了满足我们的使用需求时,我们就需要自定义函数。

(一)函数声明

Python 使用 def 关键字来声明函数,格式如下所示:

# 无参数、无返回值的函数
def 函数名():
	函数体
# 有参数、无返回值的函数
def 函数名(参数):
	函数体
	return 返回值
# 有参数、有返回值的函数
def 函数名(参数):
	函数体
	return 返回值
# 无法确定参数数量的函数
def 函数名(*args,**args):
	函数体
	return 返回值	
# 匿名函数
lambda 参数 : 表达式 

(二)函数定义

# 函数定义
# 无参数,无返回值
def print1():
    print('Hello Python!')
# 有参数,无返回值
def print2(name):
    print('Hello', name)
# 有参数,有返回值
def add1(x, y):
    sum = x + y
    print('x + y =', sum)
    return sum
# 不定长参数
def my_variable(*args):
    for p in args:
        print(p,end=',')
# 匿名函数
add2 = lambda a,b: a+b

(三)函数调用

# 函数调用
# 调用一个函数只需要知道函数名和参数即可
print1()
print2('world!')
print(add1(30,60))
my_variable(1,2,'好','perfect')
add2(50,60)

运行效果如下:

Hello Python!
Hello world!
x + y = 90
90
1,2,,perfect,

三、类的设计

Python 中类的定义使用 class 关键字,语法如下所示:

class 类名:
	属性
	...
	方法
	...

类的帮助信息可以通过ClassName.__doc__查看,class由类成员,方法,数据属性组成。

(一)基本属性

类的私有属性

__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类的方法

在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数

类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods

(二)类的定义

class Person:
'所有人员的基类'
def __init__(self, name, id):

    # 公有属性
    self.name = name
    self.id = id
    # 私有属性
    self.__age = 20

def displayName(self):
    print("Name: %s" % self.name)

def displayId(self):
    print("Id :",self.id)

#定义私有方法
def __displayAge(self):
    print("Id :",self.__age)

四、对象的使用

(一)访问自定义属性

if __name__ == '__main__':
    person = Person('张三','10001')
    print(person.name)
    person.displayId()
    person.displayName()
    print('age :',person._Person__age)
    person.__displayAge()
    # print(person.__age)

输出结果如下:

张三
Id : 10001
Name: 张三
age : 20
  File "code01.py", line 26, in <module>
    person.__displayAge()
AttributeError: 'Person' object has no attribute '__displayAge'

备注:Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性

(二)访问Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__class__: 类名
__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

相关演示代码如下:

if __name__ == '__main__':
    person = Person('张三','10001')
    print(person.__dict__)
    print(person.__doc__)
    print(person.__class__)
    print(person.__module__)

输出结果如下:

{'name': '张三', 'id': '10001', '_Person__age': 20}
None
<class '__main__.Person'>
__main__

(三)对象的注销删除

if __name__ == '__main__':
    person = Person('张三','10001')
    print(person.displayId())

    del person
    print(person.displayId())

输出效果如下:

Id : 10001
Traceback (most recent call last):
  File "code.py", line 26, in <module>
    print(person.displayId())
NameError: name 'person' is not defined

五、继承和多态

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类或父类。

# 继承语法
class 派生类名(基类名)
    ...
#多重继承
class 派生类名([基类名1,基类名2,基类名3,...])
    ...

在python中继承中的一些特点:
1、如果在子类中需要父类的构造方法就需要显示的调用父类的构造方法,或者不重写父类的构造方法。
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。
3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

(一)实现案例

class Parent:  # 定义父类
    def __init__(self,parentAttr):
        print("调用父类构造函数")
        self.parentAttr = parentAttr

    def parentMethod(self):
        print('调用父类方法')

    def setAttr(self, attr):
        self.parentAttr = attr

    def getAttr(self):
        print("父类属性 :", self.parentAttr)

class Child(Parent):  # 定义子类
    def __init__(self):
        print("调用子类构造方法")

    def childMethod(self):
        print('调用子类方法')
if __name__ == '__main__':
    c = Child()  # 实例化子类
    c.childMethod()  # 调用子类的方法
    c.parentMethod()  # 调用父类方法
    c.setAttr(200)  # 再次调用父类的方法 - 设置属性值
    c.getAttr()  # 再次调用父类的方法 - 获取属性值

输出结果如下:

调用子类构造方法
调用子类方法
调用父类方法
父类属性 : 200

(二)方法重载

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:

class Parent:  # 定义父类
    def myMethod(self):
        print('调用父类方法')

class Child(Parent):  # 定义子类
    def myMethod(self):
        print('调用子类方法')

if __name__ == '__main__':
    c = Child()  # 子类实例
    c.myMethod()  # 子类调用重写方法

好的,至此已经基本上介绍完了python的函数、类、对象和继承的基础知识,后续我将会在实战案例《tkinter实现运动的小球》中详细介绍使用面向对象的方法进行程序的搭建和实现。敬请期待。
不积跬步无以至千里,不积小流无以成江海,感谢各位的支持!

发布了15 篇原创文章 · 获赞 16 · 访问量 439

猜你喜欢

转载自blog.csdn.net/dhjabc_1/article/details/105466946