Python面向对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象相关的知识,希望对你有一定的参考价值。

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。
 
一、面向对象技术简介
  • 类(class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

  • 数据成员:类变量或者实例变量用于处理类及其例对象的相关的数据。

  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写。

  • 实例变量:定义在方法中的变量,只作用于当前实例的类。

  • 继承:即一个派生类继承基类的字段和方法。继承也允许把一个派生类的对象作为一个基类的对象对待。例如,有这样一个设计:一个dog类型的对象派生自animal类,这是模拟“是一个”关系(例如,dog是一个animal)

  • 实例化:创建一个类的实例,类的具体对象。

  • 方法:类中定义的函数

  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

 
二、什么是面向对象的程序设计及为什么要有它

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

 

优点是:极大的降低了程序的复杂度,复杂的问题简单化,流程化

缺点是:扩展性差,一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得大改,改一个组件,牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

 

面向对象的程序设计的核心是对象(上帝式思维),对象是特征(变量)与技能(函数)的结合体,要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。

在现实世界中:对象----(共同的特征与技能)--->类

在程序中:先定义类----(实例化)----->对象

 

小结:

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差

 
三、类和对象

3.1 什么是对象,什么是类

Python中一切皆为对象,且Python统一了类与类型的概念,类型就是类

类定义

语法格式如下:

 

1.
class 类名:    # 类名首字母大写
    ‘‘‘注释‘‘‘
    类体
2.
class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。

 

类对象

类对象支持两种操作:属性引用和实例化

属性引用使用和Python中所有的属性引用一样的标准语法:obj.name

类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样的:

class Myclass:
    """一个简单的类实例"""
    i=12345
    def f(self):
        return hello world
# 实例化类
x=Myclass()
# 访问类的属性和方法
print("MyClass 类的属性i为:",x.i)
print("MyClass 类的方法f输出为:",x.f())

以上创建了一个新的类实例并将对象赋给局部变量x,x为空的对象。

输出结果为:

MyClass 类的属性i为: 12345
MyClass 类的方法f输出为: hello world

 

很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为__init__()的特殊方法(构造方法),像下面这样:

 
def __init__(self):
        self.data = []    #定义空列表

当然,__init__()方法可以有参数,参数通过__init__()传递到类的实例化操作上。例如:

class Teacher:
    school=oldboy    #定义对象的共同特征
    def __init__(self,name,age):    #用户创建对象传入的参数
        self.name=name
        self.age=age
    def talk(self):
        print(is talking)
    def walk(self):
        print(is walking)
t1=Teacher(egon,23)   # 实例化:__init__(t1,‘egon‘,23)
t2=Teacher(alex,32)   # 实例化:__init__(t2,‘alex‘,32)
self代表类的实例。而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是self。
# 属性引用
# 数据属性
# print(Teacher.school)
# print(Teacher.__dict__)
# 函数属性
# print(Teacher.walk)
# print(t1.name)
# print(t2.talk)

  

类的方法

在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数,self代表的是类的实例。

#类定义
class people:
    #定义基本属性
    name = ‘‘
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))
# 实例化类
p = people(runoob,10,30)
p.speak()

类有两种作用:属性引用和实例化

1)属性引用(类名.属性)

class Student:
    school = oldboy
    def __init__(self,name,age):
        #只用来初始化的,并且一定不能有返回值
        self.name=name
        self.age=age
    def study(self):
        print(%s is studying %self.name)

s1=Student(egon,84)    #步骤一:造出对象s1  #步骤二:初始化s1,把s1,‘egon‘,84传给__init__
__init__只用来初始化函数的,并且一定不能有返回值
数据属性、函数属性:
print(Student.school)    #引用类的数据属性    #输出结果:oldboy
print(Student.study)    #引用类的函数属性    #输出结果:<function Student.study at 0x00000149F72B7620>

对象的修改、删除和添加:

#修改
Student.school=偶的博爱    #修改变量school的值
print(Student.school)        #输出结果:偶的博爱

#删除
del Student.school    #删除school属性的值
print(Student.__dict__)    #类名.__dict__:查出的是一个字典,key为属性名value为属性值

输出结果:(上面为没删除之前,删除之后,通过__dict__可查看到类的信息)
{__module__: __main__, school: 偶的博爱, __init__: <function Student.__init__ at 0x000001BB20097598>, study: <function Student.study at 0x000001BB20097620>, __dict__: <attribute __dict__ of Student objects>, __weakref__: <attribute __weakref__ of Student objects>, __doc__: None}
{__module__: __main__, __init__: <function Student.__init__ at 0x000001BB20097598>, study: <function Student.study at 0x000001BB20097620>, __dict__: <attribute __dict__ of Student objects>, __weakref__: <attribute __weakref__ of Student objects>, __doc__: None}

#添加
Student.x=6666666666666    #添加一个属性x=6666666666666
print(Student.x)    
print(Student.__dict__)    #可查看到字典里多了一值

只要是对象绑定方法都会字典传值,把自己传给函数

s1.study()   #调用函数 egon is studying

  

2)我们定义的类的属性到底存在哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
 
3)特殊的类属性
类名.__name__ # 类的名字(字符串)
类名.__doc__    # 类的文档字符串
类名.__base__    # 类的第一父类
类名.__bases__ # 类所有父类构成的元组
类名.__dict__ # 类的字典属性
类名.__module__ # 类定义所在的模块
类名.__class__ # 实例对应的类(仅新式类中)
 
4)对象/实例
对象/实例本身只有数据属性,但是Python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样
对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数
 
5)类名称空间与对象/实例名称空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:数据属性和函数属性
其中类的数据属性是共享给所有对象的,而类的函数属性是绑定到所有对象的
 
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会优先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类,最后都找不到就抛出异常
 
练习一堆类:
# 老师类
class Teacher:
    school=‘oldboy‘
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def talk(self):
        print(‘is talking‘)
    def walk(self):
        print(‘is walking‘)
t1=Teacher(‘egon‘,23)   # 实例化:__init__(t1,‘egon‘,23)
t2=Teacher(‘alex‘,32)   # 实例化:__init__(t2,‘alex‘,32)

  

# 学生类
class Student:
    job=‘student‘
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def talk(self):
        print(‘is talk‘)
    def eat(self):
        print(‘is eating‘)
s1=Student(‘buer‘,20)    # 实例化:__init__(s1,‘buer‘,20)
s2=Student(‘dongbei‘,22) # 实例化:__init__(s2,‘dongbei‘,22)
print(s1)

  

# 狗类
class Dog:
    bottle=‘dog‘
    def __init__(self,name,color):
        self.name=name
        self.color=color
    def talk(self):
        print(‘汪汪汪‘)
    def eat(self):
        print(‘dog good‘)
d1=Dog(‘哈士奇‘,‘blank‘)   # 实例化:__init__(d1,‘哈士奇‘,‘blank‘)
d2=Dog(‘泰迪‘,‘brown‘)    # 实例化:__init__(d2,‘泰迪‘,‘brown‘)

  

# 猪类
class Pig:
    bottle=‘big‘
    def __init__(self,name):
        self.name=name
    def talk(self):
        print(‘哼哼哼‘)
    def eat(self):
        print(‘pig good‘)
p1=Pig(‘xiangzhu‘)  # 实例化:__init__(p1,‘xiangzhu‘)
p2=Pig(‘huazhu‘)    # 实例化:__init__(p2,‘huazhu‘)
print(p1)

  

# 动物类
class Animal:
    local=‘zoo‘
    def __init__(self,name,kind):
        self.name=name
        self.kind=kind
    def talk(self):
        print(‘people do not know what to say‘)
    def pull(self):
        print(‘no need for toilet‘)
a1=Animal(‘xingxing‘,‘monkey‘)
a2=Animal(‘fenda‘,‘panda‘)

  

以上是关于Python面向对象的主要内容,如果未能解决你的问题,请参考以下文章

python之路之前没搞明白4面向对象(封装)

Python面向对象学习之八,装饰器

python:第二部分:面向对象:面向对象object orinted

Python 面向对象

面向面试编程代码片段之GC

面向对象编程其实很简单——Python 面向对象(初级篇)