Python一一更多实例

步骤1:创建实例

在Python中,模块名使用小写字母开头(如person.py),而类名使用一个大写字母开头(如 class Person),这是通用的惯例。

# File person.py(start)
class Person:

编写构造函数(赋值并初始化实例属性)

实例对象一般存在记录对象的属性,这些属性通常通过给类方法函数中的self属性赋值来创建。赋给实例属性第一个值的通常方法是,在__init__构造函数方法中将它们赋给self,构造函数方法包含了每次创建一个实例的时候Python会自动运行的代码。

class Person:
    def __init__(self,name,job,pay):
        self.name = name
        self.job = job
        self.pay = pay

在进行中测试

bob = Person('Bob Smith')
sue = Person('Sue Jones', job = 'dev', pay = 100000)
print(bob.name, bob.pay)
print(sue.name, sue.pay)

运行结果:

Bob Smith 0
Sue Jones 100000

以两种方式使用代码

把person.py作为顶层文件或者导入文件运行时,我们希望某些操作只在作为运行的顶层文件时才显示,可以使用__main__操作,如下所示:

if __name__ == '__main__':
    bob = Person('Bob Smith')
    sue = Person('Sue Jones', job = 'dev', pay = 100000)
    print(bob.name, bob.pay)
    print(sue.name, sue.pay)

这样,当程序以当前顶层文件运行时显示相关信息,而作为模块导入时不运行此类信息

步骤2:添加行为方法

编写方法

我们利用封装的概念添加行为方法,封装的思想就是把操作逻辑包装到界面之后,这样,每种操作在我们的程序里只编码一次。通过这种方式,如果将来需要修改,只需要修改一个版本。

class Person:
    def __init__(self,name,job = 'None',pay = 0):
        self.name = name
        self.job = job
        self.pay = pay
    def lastName(self):
        return self.name.split()[-1]
    def giveRaise(self, percent):
        self.pay = int(self.pay*(1 + percent))

if __name__ == '__main__':
    bob = Person('Bob Smith')
    sue = Person('Sue Jones', job = 'dev', pay = 100000)
    print(bob.name, bob.pay)
    print(sue.name, sue.pay)
    print(bob.lastName(),sue.lastName())
    sue.giveRaise(.10)
    print(sue.pay)

运行结果:

Bob Smith 0
Sue Jones 100000
Smith Jones
110000


步骤3:运算符重载

运算符重载:在一个类中编写这样的方法,当方法在类的实例上运行的时候,方法截获并处理内置的操作。

提供打印显示(__str__)

由于打印运行__str__并且交互提示使用__rerp__回应结果。

def __str__(self):
     return '[Person: %s, %s]' % (self.name, self.pay)

调用:

if __name__ == '__main__':
    bob = Person('Bob Smith')
    sue = Person('Sue Jones', job = 'dev', pay = 100000)
    print(bob)
    print(sue)
    print(bob.lastName(),sue.lastName())
    sue.giveRaise(.10)
    print(sue)

运行结果:

[Person: Bob Smith, 0]
[Person: Sue Jones, 100000]
Smith Jones
[Person: Sue Jones, 110000]

步骤4:通过子类定制行为

编写子类

class Manage(Person):
    def giveRaise(self, percent, bonus = .10):
        Person.giveRaise(self,percent + bonus)

调用:

tom = Manage('Tom Jones', job = 'dev', pay = 100000)
tom.giveRaise(.10)
print(tom.lastName())
print(tom)

运行结果:

Jones
[Person: Tom Jones, 120000]

测试代码的末尾按照Person的__str__中定义的漂亮格式来显示:Manager对象获取lastName,而__init__构造函数方法的代码通过继承“免费”从Person得到。

多态的作用

多态:根据对象的类型来分派具体使用哪种方法

测试如下:

print('--All three--')
for object in (bob,sue,tom):
    object.giveRaise(.10)
    print(object)

运行结果:

--All three--
[Person: Bob Smith, 0]
[Person: Sue Jones, 121000]
[Person: Tom Jones, 144000]

扩展

我们可以为Manage添加独特的、Person中没有的方法。

步骤5:定制构造函数

class Manage(Person):
    def __init__(self, name, pay):
        Person.__init__(self, name, 'mgr', pay)
    def giveRaise(self, percent, bonus = .10):
        Person.giveRaise(self,percent + bonus)

通过类名直接调用并显示地传递self实例,从而运行超类的版本。在构造的时候,Python自身使用继承来查找并调用唯一的一个__init__方法,也就是类树中最低的一个。如果你需要在构造的时候运行更高的__init__方法(并且常常会这么做),必须通过超类的名称手动调用它们。

步骤6:使用内省工具

特殊类属性

Python的内省工具,它们是特殊的属性和函数,允许我们访问对象实现的一些内部机制。

        内置的instance.__class__属性提供了一个从实例到创建它的类的链接。类反过来有一个__name__(就像模块一样),还有一个__base__序列,提供了超类的访问。我们使用这些来打印创建一个实例的类的名字,而不是通过硬编码来做到。

        内置的object.__dict__属性提供了一个字典,带有一个键/值对,以便每个属性都附加到一个命名控件对象(包括模块、类和实例)。由于它是字典,因此我们可以获取键的列表、按照键来索引、迭代其键,等等,从而广泛地处理所有的属性。我们使用这些来打印出任何实例的每个属性,而不是在定制显示中硬编码。

from person import Person
bob = Person('Bob Smith')
print(bob)

print(bob.__class__)
print(bob.__class__.__name__)

print(list(bob.__dict__.keys()))
for key in bob.__dict__:
    print(key, '=>', getattr(bob, key))

运行结果:

[Person: Bob Smith, 0]
<class 'person.Person'>
Person
['name', 'job', 'pay']
name => Bob Smith
job => None
pay => 0

一种通用显示工具

class AttrDisplay:
    def gatherAttrs(self):
        attrs = []
        for key in sorted(self.__dict__):
            attrs.append('%s=%s' % (key, getattr(self, key)))
        return ', '.join(attrs)
    def __str__(self):
        return '[%s: %s]' % (self.__class__.__name__,self.gatherAttrs())

if __name__ == '__main__':
    class TopTest(AttrDisplay):
        count = 0
        def __init__(self):
            self.attr1 = TopTest.count
            self.attr2 = TopTest.count + 1
            TopTest.count += 2
    class SubTest(TopTest):
        pass

    X, Y= TopTest(), SubTest()
    print(X)
    print(Y)

类的最终形式

要在类中使用这一通用工具,所需要做的只是从其模块导入它,使用继承将其混合到顶层类中,并且删除掉我们之前编写的专门的__str__方法。

from classtools import AttrDisplay
class Person(AttrDisplay):
    def __init__(self,name,job = 'None',pay = 0):
        self.name = name
        self.job = job
        self.pay = pay
    def lastName(self):
        return self.name.split()[-1]
    def giveRaise(self, percent):
        self.pay = int(self.pay*(1 + percent))

class Manage(Person):
    def __init__(self, name, pay):
        Person.__init__(self, name, 'mgr', pay)
    def giveRaise(self, percent, bonus = .10):
        Person.giveRaise(self,percent + bonus)

if __name__ == '__main__':
    bob = Person('Bob Smith')
    sue = Person('Sue Jones', job = 'dev', pay = 100000)
    print(bob)
    print(sue)
    print(bob.lastName(),sue.lastName())
    sue.giveRaise(.10)
    print(sue)
    tom = Manage('Tom Jones',pay = 100000)
    tom.giveRaise(.10)
    print(tom.lastName())
    print(tom)

运行结果:

步骤7:把对象存储到数据库中

Pickle和Shelve

Pickle

        任意Python对象和字节串之间的序列化

dbm(在Python2.6中叫做anydbm)

        实现一个可通过键访问的文件系统,以存储字符串

shelve

        使用另两个模块按照键把Python对象存储到一个文件中

pickle模块是一种非常通用的对象格式化和解格式化工具:对于内存中几乎任何的Python对象,它都能聪明地把对象转换为字符串,这个字符串可以随后用来在内存中重新构建最初的对象。

一个shelve的pickle化的对象看上去就像是字典一一我们通过键索引来访问、指定键来存储,并且使用len、in和dict.keys这样的字典工具来获取信息。Shelve自动地把字典操作映射到存储在文件中的对象。

对于脚本来说,一个shelve和一个常规的字典之间的唯一编码区别:一开始必须打开shelve并且在修改之后必须关闭它。实际的效果是,一个shelve提供了一个简单的数据库来按照键存储和获取本地的Python对象,并由此使他们跨程序运行而保持持久化。

在shelve数据库中存储对象:

from person import Person,Manage
bob = Person('Bob Smith')
sue = Person('Sue Jones', job = 'dev', pay = 100000)
tom = Manage('Tom Jones',50000)

import shelve
db = shelve.open('persondb')
for object in (bob, sue, tom):
    db[object.name] = object
db.close()

运行makedb.py文件后,我们在工程目录下看到产生了如下三个文件:

 

交互地探索shelve

import shelve
db = shelve.open('persondb')

print(len(db))
print(db.keys())

bob = db['Bob Smith']
print(bob)
print(bob.lastName())

for key in db:
    print(key, '=>', db[key])

for key in sorted(db):
    print(key, '=>', db[key])

运行结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值