zoukankan      html  css  js  c++  java
  • python:面向对象

    概述

    • 面向过程:根据业务逻辑从上到下写垒代码
    • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
    • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

    面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    while True
        if cpu利用率 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
     
        if 硬盘使用空间 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
     
        if 内存占用 > 80%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接

    随着时间的推移,开始使用了函数式编程,增强代码的重用性和可读性,就变成了这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    def 发送邮件(内容)
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
     
    while True
     
        if cpu利用率 > 90%:
            发送邮件('CPU报警')
     
        if 硬盘使用空间 > 90%:
            发送邮件('硬盘报警')
     
        if 内存占用 > 80%:
            发送邮件('内存报警'

    创建类和对象

     

    面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

      类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

      对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

    • class是关键字,表示类
    • 创建对象,类名称后加括号即可

    ps:类中的函数第一个参数必须是self(详细见:类的三大特性之封装)
       类中定义的函数叫做 “方法”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 创建类
    class Foo:
         
        def Bar(self):
            print 'Bar'
     
        def Hello(self, name):
            print 'i am %s' %name
     
    # 根据类Foo创建对象obj
    obj = Foo()
    obj.Bar()            #执行Bar方法
    obj.Hello('wupeiqi') #执行Hello方法 

    诶,你在这里是不是有疑问了?使用函数式编程和面向对象编程方式来执行一个“方法”时函数要比面向对象简便

    • 面向对象:【创建对象】【通过对象执行方法】
    • 函数编程:【执行函数】

    观察上述对比答案则是肯定的,然后并非绝对,场景的不同适合其的编程方式也不同。

    总结:函数式的应用场景 --> 各个函数之间是独立且无共用的数据

    语法

    类的语法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Dog(object):
     
        print("hello,I am a dog!")
     
     
    d = Dog() #实例化这个类,
    #此时的d就是类Dog的实例化对象
     
    #实例化,其实就是以Dog类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名

    上面的代码其实有问题,想给狗起名字传不进去。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Dog(object):
     
        def __init__(self,name,dog_type):
            self.name = name
            self.type = dog_type
     
        def sayhi(self):
     
            print("hello,I am a dog, my name is ",self.name)
     
     
    d = Dog('LiChuang',"京巴")
    d.sayhi()

    为什么有__init__? 为什么有self?   

    画图之前, 你先注释掉这两句

    1
    2
    3
    4
    # d = Dog('LiChuang', "京巴")
    # d.sayhi()
     
    print(Dog)

    没实例直接打印Dog输出如下

    1
    <class '__main__.Dog'>

    这代表什么?代表 即使不实例化,这个Dog类本身也是已经存在内存里的对不对, yes, cool,那实例化时,会产生什么化学反应呢?

     

    静态方法

    通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Dog(object):
     
        def __init__(self,name):
            self.name = name
     
        @staticmethod #把eat方法变为静态方法
        def eat(self):
            print("%s is eating" % self.name)
     
     
     
    = Dog("ChenRonghua")
    d.eat()

    上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。

    1
    2
    3
    4
    Traceback (most recent call last):
      File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/静态方法.py", line 17in <module>
        d.eat()
    TypeError: eat() missing 1 required positional argument: 'self'

    想让上面的代码可以正常工作有两种办法

    1. 调用时主动传递实例本身给eat方法,即d.eat(d) 

    2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了

    复制代码
     1 class Dog(object):
     2 
     3     def __init__(self,name):
     4         self.name = name
     5 
     6     @staticmethod
     7     def eat():
     8         print(" is eating")
     9 
    10 
    11 
    12 d = Dog("ChenRonghua")
    13 d.eat()
    复制代码

    类方法  

    类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Dog(object):
        def __init__(self,name):
            self.name = name
     
        @classmethod
        def eat(self):
            print("%s is eating" % self.name)
     
     
     
    = Dog("ChenRonghua")
    d.eat()

    执行报错如下,说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的

    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 16in <module>
        d.eat()
      File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/类方法.py", line 11in eat
        print("%s is eating" % self.name)
    AttributeError: type object 'Dog' has no attribute 'name'

    此时可以定义一个类变量,也叫name,看下执行效果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Dog(object):
        name = "我是类变量"
        def __init__(self,name):
            self.name = name
     
        @classmethod
        def eat(self):
            print("%s is eating" % self.name)
     
     
     
    = Dog("ChenRonghua")
    d.eat()
     
     
    #执行结果
     
    我是类变量 is eating

    属性方法  

    属性方法的作用就是通过@property把一个方法变成一个静态属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Dog(object):
     
        def __init__(self,name):
            self.name = name
     
        @property
        def eat(self):
            print(" %s is eating" %self.name)
     
     
    = Dog("ChenRonghua")
    d.eat()

    调用会出以下错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了

    1
    2
    3
    4
    5
    Traceback (most recent call last):
     ChenRonghua is eating
      File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 16in <module>
        d.eat()
    TypeError: 'NoneType' object is not callable

    正常调用如下

    1
    2
    3
    4
    5
    = Dog("ChenRonghua")
    d.eat
     
    输出
     ChenRonghua is eating
  • 相关阅读:
    数据库连接池、事务
    JDBC、单元测试、DAO模式
    归并排序
    插入排序
    MySQL数据库
    JQuery
    JavaScript
    算法训练 连续正整数的和
    算法提高 寻找三位数
    算法训练 学做菜
  • 原文地址:https://www.cnblogs.com/wzy23/p/11466792.html
Copyright © 2011-2022 走看看