python学习笔记6.2-类常见的编程模式

上一次写过一篇有关于python类的博客,现在回头去看看,发现好多语法还是比较低级,表达不是很清晰。现在谈一谈对python类的表达的新的理解。 本篇博客的重点是向大家介绍一些与类定义相关的常见的编程模式,主要包括让对象支持常见的python特性、特殊方法的使用,封装、继承,内存管理、以及一些有用的设计模式。

1 修改实例的字符串表示

在python类的定义的时候,我们可以通过定义__repr¬¬__()方法和__str__()方法来实现实例的字符串输出

1.1 特殊方法repr()返回的是实例的代码表示,也就是能通过他返回的字符串文本来重新创建这个实例,即满足obj = eval(repr(obj))。 但是如果不能做到这个条件,最好也能够让他产生一段具有帮助意义的文本,并且以< 文档 >的形式表达。 1.2 str()方法就比较好理解,它是将实例转换为字符串,用做print输出,也就是你想print()输出什么就在str()中定义什么就好。

class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return 'point({0.x!r},{0.y!r})'.format(self)

    def __str__(self):
        return '({0.x!s},{0.y!s})'.format(self)

a
Out[3]: 
point(3,4)

print(a)
(3,4)

从这个例子中我们就可以看出两者的区别。特别注意的是:(1)!r是repr()专用,一般不用在str()中(2)关于format()格式化输出会专门写一篇博客来介绍,其作用还是非常强大的。(3)0代表的是self. 0.x也就是self.x 和super()类似。

2 自定义字符串的输出格式

利用format()函数和字符串方法可以实现让对象支持自定义的输出格式,只需要在类的定义中添加format()方法。

_formats = {
    'ymd': '{d.year}-{d.mouth}-{d.day}',
    'mdy': '{d.mouth}/{d.day}/{d.year}',
    'dmy': '{d.day}/{d.mouth}/{d.year}'
            }
class Date:
    def __init__(self,year,mouth,day):
        self.year = year
        self.mouth = mouth
        self.day = day

    def __format__(self,code):
        if code == '':
            code = 'ymd'
        fmt = _formats[code]
        return fmt.format(d=self)
a = Date(2013,3,5)
print(format(a))
print(format(a,'mdy'))
print(format(a,'dmy'))

format()方法在python字符串格式化功能中提供了一个钩子,对于格式化输出的的内容完全取决于类本身,也就是编程人员自定义。一般来说格式化代码可以为任何形式。

3 让对象支持上下文管理协议

Python中对象能够支持上下文管理协议(context_management protocol),它是通过with语句触发运行,也就是在进入with语句时候创建对象,在退出with语句的时候销毁改对象。 Python中是在类的定义中使用enter()方法和exit()方法实现这个功能。

#-----------------------------------------------------------
# 这里有一个例子                        |
#-----------------------------------------------------------

4 用slot方法节约内存

针对于用作简单数据结构的类,通常可以添加slot()方法来减少其对内存的使用。当定义了slot()方法时,python就会针对实例采用一种更加紧凑的内部结构表示,不再让每个实例都创建一个dict字典。使用slot()方法的缺点就是无法再为实例添加新的属性,只能使用在定义的时候就写下的属性。 slot()方法一般被视作python的优化方法,当然有时候也用来约束程序,阻止用户为实例添加新的属性。

#-----------------------------------------------------------
# 这里有一个例子                        |
#-----------------------------------------------------------

5 python类的封装

“封装”就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体(即类);封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,特定的访问权限来使用类的成员。 与其他以来语言特性来封装类的编程语言不同的是python通过特定的命名规则来表达对数据和方法的用途。(1)任何以双下划线(__)开头的名字属于私有属性或者方法,只能在该类中被调用,不用在外部调用或者继承。同时这个规则也适用于块的定义和模块中函数的定义。

class A:
    def __init__(self):
        self.__private = 0 #私有属性
        self.public    = 0 #公有属性

    def public_method(self): #公有方法
        '''

        :return:
        '''
        print('This is a public method')

    def __private_method(self): #私有方法
        '''

        :return:
        '''
        print('This is a private method')

a = A()
a.public_method()
a.__private_method()  #会报错
print(a.__private)    #会报错

Traceback (most recent call last):
  File "D:/home/WX/test_clsaa.py", line 45, in <module>
    a.__private_method()
AttributeError: 'A' object has no attribute '__private_method'

但如果一定要访问私有属性也是可以的。使用: 实例名._类名私有属性名(例如: a._A__private )就可以访问。

class A:
    def __init__(self):
        self.__private = 0 #私有属性
        self.public    = 0 #公有属性

    def public_method(self): #公有方法
        '''

        :return:
        '''
        print('This is a public method')

    def __private_method(self): #私有方法
        '''

        :return:
        '''
        print('This is a private method')

a = A()
print(a._A__private)
a._A__private_method()

0
This is a private method

同样,私有属性和方法不能被子类继承,也不会被子类覆盖。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏测试开发架构之路

C++之new/delete/malloc/free详解

主要内容: 1.  C语言中的函数malloc和free 2.  C++中的运算符new和delete 3.  new/delete与malloc/free之间...

2845
来自专栏MasiMaro 的技术博文

C++类的构造函数与析构函数

C++中每个类都有其构造与析构函数,它们负责对象的创建和对象的清理和回收,即使我们不写这两个,编译器也会默认为我们提供这些构造函数。下面仍然是通过反汇编的方式来...

601
来自专栏CDA数据分析师

16个你绝不知道的Python神奇技能

显示有限的接口到外部 当发布python第三方package时, 并不希望代码中所有的函数或者class可以被外部import, 在__init__.py中添加...

2037
来自专栏C/C++基础

C++嵌套类与局部类

定义嵌套类的初衷是建立仅供某个类的成员函数使用的类类型。目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调...

621
来自专栏青枫的专栏

try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

602
来自专栏编程

机器学习之Python基础(二)

标题 类 面向对象 装饰器 1 类 首先举一个创建类的例子 class是声明类的关键字,human是类名,括号里的object是继承的父类(在Python2中如...

17210
来自专栏前端吧啦吧啦

涨薪必备Javascript,快点放进小口袋!

3027
来自专栏塔奇克马敲代码

第 13 章 拷贝控制

1305
来自专栏电光石火

null或空值的判断处理

1,错误用法一: if (name == "") {      //do something } 2,错误用法二: if (name.equal...

1769
来自专栏iOS122-移动混合开发研究院

【读书笔记】The Swift Programming Language (Swift 4.0.3)

素材:Language Guide 初次接触 Swift,建议先看下 A Swift Tour,否则思维转换会很费力,容易卡死或钻牛角尖。 同样是每一章只总结3...

26710

扫码关注云+社区