Chinaunix首页 | 论坛 | 博客
  • 博客访问: 59212
  • 博文数量: 5
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 55
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-13 13:01
文章分类
文章存档

2010年(5)

我的朋友

分类: Python/Ruby

2010-01-14 21:59:58

Python的模块名与类名是在两个不同的名字空间中,初学者很容易将其弄混淆。
看下面的例子:
这个例子想通过继承类ConfigParser来实现对类似windows的ini文件的操作,
修改了ConfigParser的将配置选项名全部转为小写的操作,使得配置选项名支持
大小写混用。

========================

#!/usr/bin/env python
# -*- coding: cp936 -*-

import ConfigParser

class CAppConfig(ConfigParser):
    ''' 提供配置文件的操作,增加以下功能:
    1. 大写的配置项和小写的配置项不同
    '''

    def setValue(self,section,option,value):
        ''' 修改配置项的值: [section].option=value '''       
        self.set(section,option,value)

    def getValue(self,section,option):
        ''' 获取配置项的值: [section].option '''
        try:
            value = self.get(section,option)
        except ConfigParser.NoOptionError:
            value = ""
        return value

    def optionxform(self,optionstr):
        ''' 防止大小写转换'''
        return optionstr            

    def __init__(self,filename):
        ConfigParser.__init__(self)
        self.filename=filename
        self.read(filename)

    def __del__(self):
        fp = open(self.filename,"w")
        self.write(fp)
        fp.close()
   
if __name__ == "__main__":
    config = CAppConfig("test.ini")
    print config.sections()
    print config.options("SERVER")
   
    print config.getValue("SERVER","TEST")
    print config.getValue("SERVER","test")

    config.setValue("SERVER","TEST","test")

    print config.getValue("SERVER","TEST")
    print config.getValue("SERVER","notexist")

编译这段python脚本,会提示如下错误:
    class CAppConfig(ConfigParser):
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

原因在于,import 使用的名字ConfigParser 是包名,而在类定义CAppConfig(ConfigParser)中使用是类名。因此,需要将ConfigParser换成类名:ConfigParser.ConfigParser,
修改后,发现还是有问题:
    ConfigParser.__init__(self)
TypeError: module.__init__() argument 1 must be string, not instance
Exception AttributeError: "CAppConfig instance has no attribute 'filename'" in <
bound method CAppConfig.__del__ of <__main__.CAppConfig instance at 0x00C8EAD0>>
 ignored

这个错误的原因在于, 类的初始化函数中ConfigParser.__init__(self),使用的还是类名。
那既然ConfigParserConfigParser都是类名,可以直接将 import ConfigParser修改为:
from ConfigParser import ConfigParser即可,可是这样修改后发现还有问题:
    except ConfigParser.NoOptionError:
AttributeError: class ConfigParser has no attribute 'NoOptionError'

这个错误原因在于ConfigParser使用的还是包名,在出现异常的时候,找不到包中定义的NoOptionError类。

经过这几部实验,发现ConfigParser ConfigParser使用的是包名,ConfigParserConfigParser使用的是类名。因此在最终版本中,将import ConfigParser ConfigParser.__init__不变, 将ConfigParserConfigParser修改该成为ConfigParser.ConfigParser就可以了。

======== 附件是修改后的正确代码,和测试数据。
文件:app_config.tar
大小:4KB
下载:下载


阅读(7328) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~