Python面向对象设计和面向对象编程解析

咱们都知道Python是一门灵活度很高的语言,它能够面向过程,面向对象,那咱们今天说说Python中的面向对象设计和面向对象编程的区别python

面向对象设计和面向对象编程都提到了“面向对象”, 那么首先咱们要搞清楚什么是对象编程

对象:咱们能够简单的理解为咱们见到的每一个实际存在的事物就是一个对象,若是一我的,一座房子,一只小猫等。bash

那么咱们想一想,咱们怎么面向对象,那就是以对象为中心,去描述这个对象,这个对象有什么特色,什么属性,什么功能等,想一想假如你要去向别人描述一个丢失的小猫(一个对象),你要怎么描述呢?小够的品种,大小,毛色,等等。 当你把着一些特征或者属性描述清楚以后,一个对象就被定义下来了。编程语言

知道对象的概念以后,咱们进入主题函数

1.面向对象设计

说到设计,咱们能够理解为是一种想法,思路,就是把对象的属性,功能(python里用函数表达)糅合在一块儿造成一个对象,这种思想能够简单的理解为面向对象设计,不是说必须用CLASS这种,才叫面向对象设计,下面咱们举个例子ui

def cat(name,gender,type):
    # 猫的的动做或者叫功能
    def cry(cat):
        print('一条小猫[%s],喵喵' % cat['name'])
    def run(cat):
        print('一条[%s]小猫正在跑' % cat['type'])
    def init(name,gender,type):
        cat = {
            'name':name,
            'gender': gender,
            'type': type,
            'cry':cry,
            'run':run,
        }
        return cat
    return init(name,gender,type)

cat=cat('毛球','公','波斯猫')
print(cat)
cat['cry'](cat)
复制代码

结果spa

{'name': '毛球', 'gender': '公', 'type': '波斯猫', 'cry': <function cat.<locals>.cry at 0x0000022C6C9B71E0>, 'run': <function cat.<locals>.run at 0x0000022C6C9B7158>}
一条小猫[毛球],喵喵
复制代码

上面咱们用纯函数的方式去描述了一只小猫,可是咱们也能够把上面这张方式理解为面向对象设计,由于上面咱们把猫的属性和功能函数结合在一块儿,形式了一个对象。设计

咱们用code

cat=cat('毛球','公','波斯猫')
复制代码

来生成一个对象,咱们能够调用对象的属性和函数等等,这些都是咱们熟悉的面向对象设计,可是咱们不能说这种方式叫面向对象编程。cdn

2.面向对象编程,

这个在不少语言中都在大量使用,简单的说使用Class来描述对象的方式就是面向对象编程。Python中固然也可使用面向对象编程,可是不强求,如JAVA之类的编程语言就强制要求使用面向对象编程,我的认为不太友好。下面咱们把上面的例子改为面向对象编程的方式来看看

class Cat:
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self):
        print('一条小猫[%s],喵喵' % self.name)
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
print(Cat)
cat.cry()
复制代码

上面咱们改为了个class的方式来编程,能够说就是使用面向对象编程的方式。也是咱们熟悉的类方式。

3.面向对象编程的基础知识点拨

3.1类和函数的属性分类

类属性包含:数据属性和函数属性

对象属性包括:数据属性,对象若是向调用函数属性,实际上是调用的类的函数属性

类的数据属性是全部对象共享的

类的函数属性是绑定给对象用的

怎么理解呢?咱们可使用__dict__方法来看属性

class Cat:
    weight = 5; #新定义了一个类的数据属性
    def __init__(self,name,gender,type): #实例属性
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #类的函数属性
        print('一条小猫[%s],喵喵' % self.name)
    def run(self):  #类的函数属性
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
print(Cat.__dict__)
print(cat.__dict__)
复制代码

结果

{'__module__': '__main__', 'weight': 5, '__init__': <function Cat.__init__ at 0x0000021E5DC671E0>, 'cry': <function Cat.cry at 0x0000021E5DC67158>, 'run': <function Cat.run at 0x0000021E5DC67268>, '__dict__': <attribute '__dict__' of 'Cat' objects>, '__weakref__': <attribute '__weakref__' of 'Cat' objects>, '__doc__': None}


{'name': '毛球', 'gender': '公', 'type': '波斯猫'}
复制代码

上面一行是类的属性,咱们能够看到咱们定义的weight,'cry','run'等类的数据和函数属性

下面一行是对象的属性,只有init里面定义的数据属性,没有函数属性

当函数想调用方法时,是先从本身的属性里面找,若是没有就去上层类的__dict__里面去寻找,执行,因此咱们说对象执行方法其实执行的是类的函数属性。

咱们看到上面__dict__里面还有一些其余自带属性解释以下

#python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类全部父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)
复制代码

3.2 self到底什么意思,何时使用

self咱们能够理解为实例对象本身,那为何在面向对象编程的时候,类的每一个函数都要在第一个参数放self呢? 个人理解一方面是面向对象编程的语法须要,二深层次的说是把类的数据属性和函数属性糅合在一块儿,知足面向对象设计的思想

self在对象实例化的时候,会自动传入,若是函数属性里面不定义self会报错

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
cat.cry() #对象调用类的函数属性时候,会本身传入self也就是实例本身,做为第一个参数
复制代码

结果报错

Traceback (most recent call last): File "C:/Users/aryin/Desktop/mysite2/面向对象.py", line 14, in cat.cry() TypeError: cry() takes 0 positional arguments but 1 was given

仔细看报错,cry() takes 0 positional arguments but 1 was given,说咱们给它传了一个参数,可是上面的代码里,咱们什么也没传,因此这是python本身给咱们默认传了一个self参数

那咱们看看咱们直接用类本身来调用它的函数属性,看看会不会本身传入self参数

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
Cat.cry() #类调用本身的函数属性,不传入参数
复制代码

结果报错

Traceback (most recent call last): File "C:/Users/aryin/Desktop/mysite2/面向对象.py", line 15, in Cat.cry() TypeError: cry() missing 1 required positional argument: 'self'

看错误是少了一个参数,说明当类本身调用函数属性的时候,不会本身传入self,cry函数须要一个参数self,因此报错了,因此正确的使用是

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
Cat.cry(cat) #类调用本身的函数属性,不传入参数
复制代码

因此只有当对象去调用类的函数属性或者说方法的时候才会自动传入self属性,类本身调用时候不会,要本身传入实例。

固然咱们通常不这么使用类来调用本身的函数属性,咱们可使用类方法来实现调用

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    @classmethod
    def cry(cls): #没有写self print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

Cat.cry()
复制代码

结果:

一条小猫喵喵

这里看到改动的地方,是传入的cls, 就是类本身,classmethod类静态方法实现类调用本身的函数属性时候不须要显示传入cls参数,而是自动传入,classmethod类静态方法实际就是绑定了类和本身的函数属性。

3.3 实例化到底作了什么(__init__方法)

当对象实例化的时候,会先去执行__init__函数,对象会去__init__里面找到本身的数据属性

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        print('开始初始化')
        self.name = name
        self.gender = gender
        self.type = type
        print('结束初始化')


    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat=Cat('毛球','公','波斯猫') #实例化
print(cat.__dict__)
复制代码

结果:

开始初始化 结束初始化 {'name': '毛球', 'gender': '公', 'type': '波斯猫'}

看到__init__函数里面已经执行了,对象的数据属性也获得了。

今天说到这里,我的意见,望指教。

更多源代码文章请关注:pythonislover

相关文章
相关标签/搜索