自动化运维Python系列(六)之面向对象

面向对象编程

面向过程:根据业务逻辑从上到下垒代码

函数式:将某功能代码封装到函数中,以后直接调用,不需要再次编写

面向对象:对函数进行分类和封装,让开发“更快更好更强...”

# 像Java和C#等编程语言仅支持面向对象编程,而Python支持函数式编程和面向对象编程混用

面向对象示例

# 函数式编程
def bar():
    print(‘bar‘)
 
bar()  # 直接调用函数
# 面向对象编程
class Foo:  # 创建类
  
    def bar(self):  # 在类里面定义函数 这里self是一个特殊的参数 创建对象时Foo将自身传进来
        print(‘bar‘)
 
obj = Foo()  # 创建一个对象
obj.bar()  # 由对象去访问类里面函数

面向对象的三大特性:封装 继承 多态

封装

将我们需要的内容封装进创建的类,需要的时候再去调用

class Foo:  # 创建类
 
    def __init__(self, name, age):  # Foo接收到两个参数后会封装在自己类内部
        self.name = name
        self.age = age
 
 
obj = Foo(‘kobe‘, 18)  # 创建一个对象 传两个参数
print(obj.name, obj.age)  # 外面调用封装好的参数
 
输出:
kobe 18

类成员

字段:普通字段、静态字段

方法:普通方法、静态方法、类方法

属性:普通属性

1)字段(类里面封装的参数)

class Foo:
    # 字段(静态字段 保存在类里面)
    CC = "中国"
    def __init__(self, name):
        # 字段(普通的字段 保存在对象里面)
        self.name = name
 
# 普通字段通过对象访问
obj = Foo(‘上海‘)
print(obj.name)
# 静态字段通过类访问
print(Foo.CC)

2)方法(类里面封装的函数)

class Foo:
 
    def show(self):
              # 普通方法:对象调用执行 方法属于类
        print(self.name)
 
    @staticmethod
    def f1():
        # 静态方法 由类调用执行
        print(‘f1‘)
 
    @classmethod
    def f2(cls):  # class 自动给类名传进去了
        # 类方法
        # cls 是类名 加()创建对象
        print(cls)
 
# 创建对象
obj = Foo()
# 通过对象去访问普通方法 
obj.show()
# 通过类去访问静态方法
Foo.f1()
# 类方法 会将类 Foo 名字直接传入函数
Foo.f2()

3)属性

在没有定义类的属性之前,我们访问类中的方法需要在方法名后面加括号():比如 obj.f1()

定义属性之后,我们访问类中的方法可以直接 obj.f1

class Foo:
    @property
    def f1(self):
        print(‘f1‘)
 
obj = Foo()
obj.f1  # 无需加括号直接通过对象访问

可设置、可删除

class Foo:
 
    @property  # 在类方法上加上 property装饰器 
    def f1(self):
        print(‘f1‘)
 
    @f1.setter  # 设置数值
    def f1(self, values):
        print(values)
 
    @f1.deleter  # 可删除
    def f1(self):
        print(‘del...‘)
 
obj = Foo()
obj.f1  # 无需加括号直接通过对象访问
 
obj.f2 = 100
del obj.f1
 
输出:
f1
del...

类属性的另一种写法

class Foo:
 
    def f1(self):
        return 100
 
    def f2(self, value):
        print(value)
 
    def f3(self):
        print(‘300‘)
      
    # 类属性定义
    Foo = property(fget=f1, fset=f2, fdel=f3)
 
obj = Foo()
 
# 取值
ret = obj.Foo
print(ret)
 
# 赋值
obj.Foo = 200
 
# 删除
del obj.Foo
 
# 输出
100
200
300

类成员修饰符

类成员修饰符:将类中的字段或者方法定义为公有或私有

公有成员:在任何地方都可以访问

私有成员:只有在类内部才能被访问

class Foo:
 
    __cc = 123
 
    def __init__(self, name):
        self.__name = name  # 加两个下划线__表示私有字段 外部、继承都不能调用
 
    def f1(self):
        print(self.__name)
 
    @staticmethod  # 加 staticmethod 装饰器表示为静态方法,可以不加self参数直接外部调用
    def f3(self):
        print(Foo.__cc)
 
obj = Foo(‘kobe‘)
# print(obj.__name)  # 通过对象外部访问内部普通字段不成功
obj.f1()
 
# print(Foo.__cc)  # 通过外部访问内部静态字段也不成功
obj.f3()
 
# 特殊访问方法
print(obj._Foo__name)

类的特殊成员

__doc__       # 类的描述信息

__module__     # 当前对象在哪个模块

__class__      # 当前对象属于哪个类

__str__       # 打印对象时返回的值

__init__      # 构造方法

__del__       # 析构方法

__call__      # 对象后加括号触发执行

__dict__      # 类或对象中的所有成员

__getitem__    # 索引操作如字典

__setitem__    # 索引操作

__delitem__    # 索引操作

1)__doc__ 描述信息

class Foo:
    """
    注释 __doc__
    """
obj = Foo()
print(obj.__doc__)
输出:
注释 __doc__
2)__module__ 和 __class__
from lib.aa import C
 
obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

3)__init__ 和 __str__

class Foo:
 
    def __init__(self, name, age):  # 构造方法
        self.name = name
        self.age = age
    def __str__(self):  # str方法
        return ‘%s - %s ‘ % (self.name, self.age)
 
obj1 = Foo(name=‘kobe‘, age=18)
obj2 = Foo(name=‘jordan‘, age=18)
print(obj1)
print(obj2)

# 输出:
kobe - 18 
jordan - 18

4)__del__

class Foo:
  
    def __init__(self, name, age):  # 构造方法
        self.name = name
        self.age = age
  
    # 析构方法:在垃圾回收之前执行
    def __del__(self):
        pass

5)__call__

class Foo:
 
    def __call__(self, *args, **kwargs):
        print(‘call‘)
 
p = Foo()
 
# 对象后面加括号执行 __call__ 方法
p()
# 一个括号是类创建了一个对象 两个括号是去执行 __call__ 方法
Foo()()
 
# 输出:
call
call

6)__dict__

class Foo:
  
    def __init__(self, name, age):  # 构造方法
        self.name = name
        self.age = age
  
obj1 = Foo(name=‘kobe‘, age=18)
 
# 获取对象中封装的数据返回一个字典
ret = obj1.__dict__
print(ret)
# 输出:
{‘name‘: ‘kobe‘, ‘age‘: 18}
 
# 全部的类方法
# print(Foo.__dict__)

6)__getitem__ __setitem__ delitem__ 用于索引操作、如字典:可以获取值、设置、删除

class Foo:
 
    def __getitem__(self, item):
        print(‘getitem‘)
 
    def __setitem__(self, key, value):
        print(‘setitem‘)
print(item.start, item.stop, item.step)
 
    def __delitem__(self, key):
        print(‘delitem‘)
 
# 中括号语法自动执行 getitem 方法
obj = Foo()
obj[‘ab‘]
 
# 中括号并且赋值执行 setitem 方法
obj[‘k1‘] = 111
del obj[‘k1‘]
 
# 切片也是去执行 setitem 方法
obj[1:6:2]
 
# 输出
setitem
delitem
getitem
1 6 2

7)__iter__、 __isinstance__、__issubclass__

class Bar:
    pass
 
class Foo(Bar):
    
    # 返回一个可迭代对象
    def __iter__(self):
        # return iter([11, 22, 33, 44])
        yield 1
        yield 2
 
obj = Foo()
for item in obj:
    print(item)
 
# 查看 obj 是否是 Foo 的实例
ret = isinstance(obj, Foo)
# 也可以查看是否是 父类 的实例
# ret = isinstance(obj, Bar)
print(ret)
 
# 查看 Foo 是否为 Bar 的子类
ret1 = issubclass(Foo, Bar)
print(ret1)
 
# 输出
1
2
True
True

super 

super 是为了解决Python中的多重继承问题,强行去执行父类中的方法

class C1:
 
    def f1(self):
        print(‘c1.f1‘)
 
class C2(C1):
 
    def f1(self):
        # 主动执行父类的 f1 方法
        super(C2, self).f1()
        print(‘c2.f1‘)
 
obj = C2()
obj.f1()
# 输出:
c1.f1
c2.f1

利用super在不改变源代码情况添加功能的方法

目录
backend
  - commons.py
index.py
lib.py
setting.py
 
commons.py >>
class Foo:
    def f1(self):
        print(‘Foo.f1‘)
 
index.py >>
from setting import ClassName
from setting import Path
 
def execute():
    model = __import__(Path, fromlist=True)
    cls = getattr(model, ClassName)
    obj = cls()
    obj.f1()
 
if __name__ == ‘__main__‘:
    execute()
 
setting >>
# Path = "backend.commons"
# ClassName = ‘Foo‘
 
Path = "lib"
ClassName = ‘MyFoo‘
 
lib >>
from backend.commons import Foo
 
class MyFoo(Foo):
 
    def f1(self):
        print(‘before‘)
        super(MyFoo, self).f1()
        print(‘after‘)
这样运行我们自己添加的lib 时结果如下
before
Foo.f1
after

利用super实现有序字典

class MyDict(dict):
 
    def __init__(self):
        self.li = []
        super(MyDict, self).__init__()
 
    def __setitem__(self, key, value):
        self.li.append(key)
        super(MyDict, self).__setitem__(key, value)
 
    def __str__(self):
        temp_list = []
        for key in self.li:
            value = self.get(key)
            temp_list.append("‘%s‘:%s" % (key, value))
        temp_str = "{" + ",".join(temp_list) + "}"
        return temp_str
 
obj = MyDict()
obj[‘k1‘] = 123
obj[‘k2‘] = 456
print(obj)
 
# 输出
{‘k1‘:123,‘k2‘:456}

单例模式

# 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

class Foo:
 
    instance = None
    def __init__(self, name):
        self.name = name
 
    @classmethod
    def get_instance(cls):
        if cls.instance:
            return cls.instance
        else:
            obj = cls(‘alex‘)
            cls.instance = obj
            return obj
 
obj1 = Foo.get_instance()
obj2 = Foo.get_instance()
print(obj1)
print(obj2)
# 输出
<__main__.Foo object at 0x000001C09B130B70>
<__main__.Foo object at 0x000001C09B130B70>

异常处理

while True:
 
    num1 = input(‘num1: ‘)
    num2 = input(‘num2: ‘)
 
    try:
        num1 = int(num1)
        num2 = int(num2)
        ret = num1 + num2
 
    except Exception as ex:
        print(ex)
    except ValueError as ex:
        print(ex)
    except IndexError as ex:
        print(ex)

异常处理完整代码

try:
    raise Exception(‘主动错误一下...‘)
    pass
except ValueError as ex:
    print(ex)
except Exception as ex:
    print(ex)
else:
    pass
finally:
    pass
时间: 2024-10-27 14:14:10

自动化运维Python系列(六)之面向对象的相关文章

自动化运维Python系列(一)之基础篇

Python介绍 Python是由创始人吉多·范罗苏姆(Guido van Rossum)在1989年圣诞节假期期间,为了打发时间,构思出来的一个新的脚本解释器.由于Guido在开发Python语言过程中,借鉴了很多ABC语言特性,所有后来包括Guido自己也那么认为,Python语言的前身就是ABC语言. Python是一门面向对象的.动态解释型强定义语言:Python崇尚简洁.优美.清晰,是一门优秀的被广泛使用的语言. 在2015年以前,最流行的Python版本还是2.4,但是由于Pytho

自动化运维Python系列之ForeignKey、relationship联表查询

一对多和多对多 数据库表结构设计是程序项目开发前的重要环节,后期数据库操作都是围绕着这个已经设计好的表结构进行,如果表结构设计有问题,整个程序项目就有存在需要整个推翻重构的风险... 数据库表结构除了简单的单表操作以外,还有一对多.多对多等. 一对多 基于SQLAlchemy我们可以先创建如下结构的2张表,然后来看看具体怎样通过外键ForeignKey或者relationship联表操作 创建表 from sqlalchemy.ext.declarative import declarative

自动化运维Python系列(七)之Socket编程

了解知识点TCP\IP 要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准, 从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族.不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中(数据链路层和物理

自动化运维Python系列(三)之基础函数和文件操作

函数作用 增强代码的重用性和可读性 在没有使用函数编程之前,我们可能一直遵循的都是面向过程编程,即根据业务逻辑从上到下实现各个功能,这样的做的坏处是代码可读性不强,大量冗余代码,而且执行效率不高:有了函数后,我们就可以将多次使用到的相同代码模块放在单独的函数定义中,在任何想要调用它的地方随时调用,这就叫做函数式编程. 面向对象编程其实就是对函数进行再分类和封装,让开发"更快更好更强..." 函数的定义 def 函数名(参数): ... 函数体 ... 返回值 函数的定义主要有如下要点:

自动化运维Python系列(四)之装饰器和生成器

装饰器 在理解什么事装饰器之前,我们需要理解:函数也是一个对象,可以赋值给变量,通过变量来调用 def f1():     print('2016') d = f1 d() 输出: 2016 那么装饰器的作用就是在不改变原函数的前提下,调用这些函数,并且为函数增加我们需要的新功能. 我们平时在编写好很多独立函数模块以后,突然需要在每个模块内添加一个功能,比如: def f1():     print('F1') def f2():     print('F2') def f3():     pr

自动化运维Python系列之Django进阶操作

FBV && CBV FBV.CBV是Django视图路由处理模型,当用户请求送达路由系统URL后,由其转发给视图view来分析并处理 // FBV    function base views  // CBV    class base views 区别就是一个直接用函数驱动,一个用类驱动,两者在使用上存在一些区别 1)FBV URL中根据路由匹配直接转发给视图中的某一个处理函数 urlpatterns = [     url(r'^home/', views.home), ] 视图函数

自动化运维Python系列之Django信号、缓存操作

Django信号 Django内部提供了一种"信号强度"处理机制,简单理解就是当Django在接收到请求后内部做某些特定操作前发出信号,提醒一些接受者或者做操作,这样的好处就是方便程序定制小功能插件,也是对本身框架的一种节藕操作 1)Django的内置信号 Model signals     pre_init                # django的modal执行其构造方法前,自动触发     post_init               # django的modal执行其构

自动化运维Python系列之消息队列RabbitMQ

RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco .Redhat.iMatix 等联合制定了 AMQP 的

自动化运维Python系列之Memcache、Redis操作

Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. Memcached安装 wget http://memcached.org/latest tar -zxvf memcach