python之面向对象基础一

简介: python之面向对象基础一

假设我们要处理学生的成绩表,为了表示一个学生的成绩:

面向过程的方法:用一个dict表示,在进行函数调用

std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }
#而处理学生成绩可以通过函数实现,比如打印学生的成绩:
def print_score(std):
    print('%s: %s' % (std['name'], std['score']))
print_score(std2)
print_score(std1)
Bob: 81
Michael: 98

面向对象的方法:创建出这个学生对应的对象,给对象发一个print_score消息,让对象自己把自己的数据打印出来。

class Student(object):
    # 定义初始化方法,创建实例对象自动调用,对属性赋值
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print('%s: %s' % (self.name, self.score))
hongenjie = Student('洪恩节',100)
lisa = Student('Lisa Simpson', 87)
hongenjie.print_score()
lisa.print_score()
洪恩节: 100
Lisa Simpson: 87

面向对象和面向程序的区别:

如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,

而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性。

如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,

给对象发一个print_score消息,让对象自己把自己的数据打印出来,给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法


面向对象的设计思想是抽象出Class,根据类创建实例,面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法


创建对象和定义类:

经典类:class Cat:

# 定义一个猫类
class Cat:
    # 定义猫的属性(color,legs)
    color = '黄色'
    legs = 4
    # 定义猫的方法(eat,sleep)
    def eat(self):
        print('猫吃鱼')
    def sleep(self):
        print('猫睡觉')
my_cat=Cat()#创建实例my_cat
my_cat.eat()#访问方法
my_cat.sleep()#访问方法
print(Cat.color)#访问属性
print(Cat.legs)#访问属性
猫吃鱼
猫睡觉
黄色
4

新式类:class Car(object):

# 定义一个车类
class Car(object):
    # 属性:颜色,四个轮子
    color = '白色'
    wheel = 4
    # 行为:跑,鸣笛
    def move(self):
        print('车子在移动')
    def whistle(self):
        print('车子在鸣笛')
my_car=Car()
my_car.move()
my_car.whistle()
print(Car.color)
print(Car.wheel)
车子在移动
车子在鸣笛
白色
4
实例的作用:

当创建实例对象的时候,对象自动拥有方法,对象就可以直接调用方法(属性也一样)。

对象属性的添加和获取:

属性的添加语法格式:对象名.属性名 = 新的值

属性的获取语法格式:print(对象名.属性名)

对象调用的方法语法格式:对象名.方法名()

#定义一个关于person的类
class Person(object):#属性:身高,体重,年龄#行为:吃饭 睡觉 喝水
  #定义普通的方法
    def eat(self):
        print('人都要吃饭')
    def sleep(self):
        print('人都要休息')
    def drink(self):
        print('水是生命之源')
#通过Person创建一个实例对象p
p = Person()
#直接添加属性
p.name = '张三'
p.age = 20
p.height=180
p.weight=60
#获取属性
print(p.name)
print(p.age)
print(p.height)
print(p.weight)
#对象调用方法
p.eat()
p.sleep()
p.drink()
张三
20
180
60
人都要吃饭
人都要休息
水是生命之源

不仅如此,我们还可以创建新的对象p2,它可以和p有不同的属性,但他们含有相同的方法。

#通过Person创建一个对象p2
p2 = Person()
#直接添加属性
p2.name = '李四'
p2.age = 30
p2.sex = '男'
#获取属性
print(p2.name,p2.age,p2.sex)
#对象调用方法
p2.eat()
p2.sleep()
p2.drink()
李四 30 男
人都要吃饭
人都要休息
水是生命之源

类中的函数称为方法,我们在python前面的基础学习中,学到的任何函数都适用于方法,唯一的区别在于调用方法的方式不同。

init()方法的使用:

init(self,属性1,属性2)是一个特殊的方法,每当我们所创建的类产生新的示例的时候,python都会自动运行它,在这个运行方法的名称中,开头和末尾均有两个下划线,这是避免与普通方法名称产生矛盾,因此必须确保__init__(self,属性1,属性2)的两边都有两个下划线,否则当你使用类来创建示例时,将不会自动调用这个方法,进而引发难以发现的错误。

举例:

#定义一个汽车类
class Car(object):
    def __init__(self,color,wheelNum):
        self.color = color
        self.wheelNum = wheelNum
    # 定义一个普通方法
    def move(self):
        print('车子在移动')
    # 定义一个普通方法
    def whistle(self):
        print('车子在鸣笛')
#创建一个对象bmw
bmw = Car('红色',4)
#调用类里面普通方法
bmw.move()
bmw.whistle()
print(bmw.color)
print(bmw.wheelNum)

细心的小伙伴可能都发现了为什么__init_()属性里面包含了self.

为何必须在方法定义中包含形参self呢?

因为python调用这个方法创建示例时,将自动传入实参self,每个与示例相关联的方法调用都自动传递实参self,它是一个指向示例本身的引用,让示例能够访问类中的属性和方法。

属性我们可以在编写__init__()的时候将属性的值指定,也可以是通过实参来传递属性的值。


指定属性的值:

def __init__(self,color,wheelNum):
        self.color = '黑色'
        self.wheelNum = 4

不指定属性的值:

def __init__(self,color,wheelNum):
        self.color = color
        self.wheelNum = wheelNum

那么这两种有什么区别?

区别在于如果指定了属性的值,那么在调用属性的时候,即使实参传递了和指定值不相同的,输出结果依然为指定值。

举例:

def __init__(self,color,wheelNum):
    self.color = '黑色'
    self.wheelNum = 4
bmw = Car('红色',4)
print(bmw.color)
print(bmw.wheelNum)
黑色
4

难道属性的值就不能被改变吗?当然不是

下面我们对上面例子中的属性进行修改:

bmw.color="yellow"
bmw.wheelNum=10

直接修改 对象名.属性名 = 新值

完整代码:

class Car(object):
    def __init__(self,color,wheelNum):
        self.color = '黑色'
        self.wheelNum = 4
    def move(self):
        print('车子在移动')
    def whistle(self):
        print('车子在鸣笛')
bmw = Car('红色',4)
bmw.move()
bmw.whistle()
bmw.color="yellow"
bmw.wheelNum=10
print(bmw.color)
print(bmw.wheelNum)

这次的颜色和车轮数很好的被修改了

车子在移动
车子在鸣笛
yellow
10

当实例化类得到具体对象的时候,会自动调用__init__()方法,对类的属性进行初始化赋值,创建对象的时候,自动拥有类里面属性

__del__析构方法:

import time
#定义一个动物类
class Animal(object):
    #定义初始化方法  创建对象时候自动调用
    def __init__(self,name):
        print('__init__方法被调用')
        self.name = name
    #定义普通方法
    def walk(self):
        print('动物会跑')
    #定义一个析构方法  删除对象的时候自动调用
    def __del__(self):
        print('__del__方法被调用')
        print('%s对象被干掉'%(self.name))
#创建一个dog对象
dog = Animal('哈皮狗')
dog.walk()
__init__方法被调用
动物会跑
__del__方法被调用
哈皮狗对象被干掉


通过输出结果我们发现,为什么__del__()也被调用了呢?

原因是:析构函数__del__(),使用del删除实例时才触发,否则等到文件执行完毕进行回收时才触发。

修改之后:

import time
# 定义一个动物类
class Animal(object):
    #定义初始化方法  创建对象时候自动调用
    def __init__(self,name):
        print('__init__方法被调用')
        self.name = name
    #定义普通方法
    def walk(self):
        print('动物会跑')
    #定义一个析构方法  删除对象的时候自动调用
    def __del__(self):
        print('__del__方法被调用')
        print('%s对象被干掉'%(self.name))
#创建一个dog对象
dog = Animal('哈皮狗')
dog.walk()
# 手动销毁对象,再测试对象调用类中方法报错
del dog
dog.walk()

此时编译器告诉我们dog没有被定义,事实上是因为使用del将其删除了



上面代码中,dog只被引用了一次,因此使用一次del,该对象就被真正的删除了,那么如果是下面这种情况呢?

cat被引用了3次,如果我们去用和面一样的方法,会成功实现对象的删除吗?

cat=Animal("波斯猫")
cat2=cat
cat3=cat

删除cat,去调用cat2和cat3

class Animal(object):
    def __init__(self,name):
        print('__init__方法被调用')
        self.name = name
    def walk(self):
        print('动物会跑')
    def __del__(self):
        print('__del__方法被调用')
        print('%s对象被干掉'%(self.name))
cat=Animal("波斯猫")
cat2=cat
cat3=cat
del cat
cat3.walk()
cat2.walk()


__init__方法被调用
动物会跑
动物会跑
__del__方法被调用
波斯猫对象被干掉

cat2和cat3成功被调用了,难道是对象没被删除?下面我们调用一下cat.

class Animal(object):
    def __init__(self,name):
        print('__init__方法被调用')
        self.name = name
    def walk(self):
        print('动物会跑')
    def __del__(self):
        print('__del__方法被调用')
        print('%s对象被干掉'%(self.name))
cat=Animal("波斯猫")
cat2=cat
cat3=cat
del cat
cat.walk()
Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/main.py", line 295, in <module>
    cat.walk()
NameError: name 'cat' is not defined
__init__方法被调用
__del__方法被调用
波斯猫对象被干掉

通过结果我们可得出如下结论:

在本例中,cat被删除,但不影响cat2/cat3的调用,其他情况亦是如此。


变量保存了对象的引用,对象的引用计数加1,使用__del__()删除对象的时候,对象的引用计数-1,对象被删除,如果对象的引用计数不是1,每删除一次对象的引用计数减1,直到引用计数为0时候,该对象才被真正的删除

相关文章
|
4月前
|
Java 程序员 C++
Python 面向对象详解!
本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。
111 2
|
2月前
|
关系型数据库 开发者 Python
Python编程中的面向对象设计原则####
在本文中,我们将探讨Python编程中的面向对象设计原则。面向对象编程(OOP)是一种通过使用“对象”和“类”的概念来组织代码的方法。我们将介绍SOLID原则,包括单一职责原则、开放/封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则有助于提高代码的可读性、可维护性和可扩展性。 ####
|
6月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
65 0
|
4月前
|
Python
Python面向对象(2)
【10月更文挑战第14天】
Python面向对象(2)
|
4月前
|
设计模式 程序员 C语言
Python面向对象
【10月更文挑战第13天】
Python面向对象
|
8月前
|
Python
Python进阶第一篇(Python的面向对象)
Python进阶第一篇(Python的面向对象)
|
9月前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
136 1
|
5月前
|
前端开发 Python
Python编程的面向对象有哪些(二)
Python编程的面向对象(二)—类的多态
37 7
|
5月前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
9月前
|
人工智能 自然语言处理 开发者
Python基础教程——面向对象
Python基础教程——面向对象

热门文章

最新文章