在python中修改.properties文件的操作


Posted in Python onApril 08, 2020

在java 编程中,很多配置文件用键值对的方式存储在 properties 文件中,可以读取,修改。而且在java 中有 java.util.Properties 这个类,可以很方便的处理properties 文件, 在python 中虽然也有读取配置文件的类ConfigParser, 但如果习惯java 编程的人估计更喜欢下面这个用python 实现的读取 properties 文件的类:

"""
A Python replacement for java.util.Properties class
This is modelled as closely as possible to the Java original. 
"""

import sys,os
import re
import time

class IllegalArgumentException(Exception):

  def __init__(self, lineno, msg):
    self.lineno = lineno
    self.msg = msg

  def __str__(self):
    s='Exception at line number %d => %s' % (self.lineno, self.msg)
    return s

class Properties(object):
  """ A Python replacement for java.util.Properties """

  def __init__(self, props=None):

    # Note: We don't take a default properties object
    # as argument yet

    # Dictionary of properties.
    self._props = {}
    # Dictionary of properties with 'pristine' keys
    # This is used for dumping the properties to a file
    # using the 'store' method
    self._origprops = {}

    # Dictionary mapping keys from property
    # dictionary to pristine dictionary
    self._keymap = {}

    self.othercharre = re.compile(r'(?<!\\)(\s*\=)|(?<!\\)(\s*\:)')
    self.othercharre2 = re.compile(r'(\s*\=)|(\s*\:)')
    self.bspacere = re.compile(r'\\(?!\s$)')

  def __str__(self):
    s='{'
    for key,value in self._props.items():
      s = ''.join((s,key,'=',value,', '))

    s=''.join((s[:-2],'}'))
    return s

  def __parse(self, lines):
    """ Parse a list of lines and create
    an internal property dictionary """

    # Every line in the file must consist of either a comment
    # or a key-value pair. A key-value pair is a line consisting
    # of a key which is a combination of non-white space characters
    # The separator character between key-value pairs is a '=',
    # ':' or a whitespace character not including the newline.
    # If the '=' or ':' characters are found, in the line, even
    # keys containing whitespace chars are allowed.

    # A line with only a key according to the rules above is also
    # fine. In such case, the value is considered as the empty string.
    # In order to include characters '=' or ':' in a key or value,
    # they have to be properly escaped using the backslash character.

    # Some examples of valid key-value pairs:
    #
    # key   value
    # key=value
    # key:value
    # key   value1,value2,value3
    # key   value1,value2,value3 \
    #     value4, value5
    # key
    # This key= this value
    # key = value1 value2 value3

    # Any line that starts with a '#' is considerered a comment
    # and skipped. Also any trailing or preceding whitespaces
    # are removed from the key/value.

    # This is a line parser. It parses the
    # contents like by line.

    lineno=0
    i = iter(lines)

    for line in i:
      lineno += 1
      line = line.strip()
      # Skip null lines
      if not line: continue
      # Skip lines which are comments
      if line[0] == '#': continue
      # Some flags
      escaped=False
      # Position of first separation char
      sepidx = -1
      # A flag for performing wspace re check
      flag = 0
      # Check for valid space separation
      # First obtain the max index to which we
      # can search.
      m = self.othercharre.search(line)
      if m:
        first, last = m.span()
        start, end = 0, first
        flag = 1
        wspacere = re.compile(r'(?<![\\\=\:])(\s)')    
      else:
        if self.othercharre2.search(line):
          # Check if either '=' or ':' is present
          # in the line. If they are then it means
          # they are preceded by a backslash.

          # This means, we need to modify the
          # wspacere a bit, not to look for
          # : or = characters.
          wspacere = re.compile(r'(?<![\\])(\s)')    
        start, end = 0, len(line)

      m2 = wspacere.search(line, start, end)
      if m2:
        # print 'Space match=>',line
        # Means we need to split by space.
        first, last = m2.span()
        sepidx = first
      elif m:
        # print 'Other match=>',line
        # No matching wspace char found, need
        # to split by either '=' or ':'
        first, last = m.span()
        sepidx = last - 1
        # print line[sepidx]


      # If the last character is a backslash
      # it has to be preceded by a space in which
      # case the next line is read as part of the
      # same property
      while line[-1] == '\\':
        # Read next line
        nextline = i.next()
        nextline = nextline.strip()
        lineno += 1
        # This line will become part of the value
        line = line[:-1] + nextline

      # Now split to key,value according to separation char
      if sepidx != -1:
        key, value = line[:sepidx], line[sepidx+1:]
      else:
        key,value = line,''

      self.processPair(key, value)

  def processPair(self, key, value):
    """ Process a (key, value) pair """

    oldkey = key
    oldvalue = value

    # Create key intelligently
    keyparts = self.bspacere.split(key)
    # print keyparts

    strippable = False
    lastpart = keyparts[-1]

    if lastpart.find('\\ ') != -1:
      keyparts[-1] = lastpart.replace('\\','')

    # If no backspace is found at the end, but empty
    # space is found, strip it
    elif lastpart and lastpart[-1] == ' ':
      strippable = True

    key = ''.join(keyparts)
    if strippable:
      key = key.strip()
      oldkey = oldkey.strip()

    oldvalue = self.unescape(oldvalue)
    value = self.unescape(value)

    self._props[key] = value.strip()

    # Check if an entry exists in pristine keys
    if self._keymap.has_key(key):
      oldkey = self._keymap.get(key)
      self._origprops[oldkey] = oldvalue.strip()
    else:
      self._origprops[oldkey] = oldvalue.strip()
      # Store entry in keymap
      self._keymap[key] = oldkey

  def escape(self, value):

    # Java escapes the '=' and ':' in the value
    # string with backslashes in the store method.
    # So let us do the same.
    newvalue = value.replace(':','\:')
    newvalue = newvalue.replace('=','\=')

    return newvalue

  def unescape(self, value):

    # Reverse of escape
    newvalue = value.replace('\:',':')
    newvalue = newvalue.replace('\=','=')

    return newvalue  

  def load(self, stream):
    """ Load properties from an open file stream """

    # For the time being only accept file input streams
    if type(stream) is not file:
      raise TypeError,'Argument should be a file object!'
    # Check for the opened mode
    if stream.mode != 'r':
      raise ValueError,'Stream should be opened in read-only mode!'

    try:
      lines = stream.readlines()
      self.__parse(lines)
    except IOError, e:
      raise

  def getProperty(self, key):
    """ Return a property for the given key """

    return self._props.get(key,'')

  def setProperty(self, key, value):
    """ Set the property for the given key """

    if type(key) is str and type(value) is str:
      self.processPair(key, value)
    else:
      raise TypeError,'both key and value should be strings!'

  def propertyNames(self):
    """ Return an iterator over all the keys of the property
    dictionary, i.e the names of the properties """

    return self._props.keys()

  def list(self, out=sys.stdout):
    """ Prints a listing of the properties to the
    stream 'out' which defaults to the standard output """

    out.write('-- listing properties --\n')
    for key,value in self._props.items():
      out.write(''.join((key,'=',value,'\n')))

  def store(self, out, header=""):
    """ Write the properties list to the stream 'out' along
    with the optional 'header' """

    if out.mode[0] != 'w':
      raise ValueError,'Steam should be opened in write mode!'

    try:
      out.write(''.join(('#',header,'\n')))
      # Write timestamp
      tstamp = time.strftime('%a %b %d %H:%M:%S %Z %Y', time.localtime())
      out.write(''.join(('#',tstamp,'\n')))
      # Write properties from the pristine dictionary
      for prop, val in self._origprops.items():
        out.write(''.join((prop,'=',self.escape(val),'\n')))

      out.close()
    except IOError, e:
      raise

  def getPropertyDict(self):
    return self._props

  def __getitem__(self, name):
    """ To support direct dictionary like access """

    return self.getProperty(name)

  def __setitem__(self, name, value):
    """ To support direct dictionary like access """

    self.setProperty(name, value)

  def __getattr__(self, name):
    """ For attributes not found in self, redirect
    to the properties dictionary """

    try:
      return self.__dict__[name]
    except KeyError:
      if hasattr(self._props,name):
        return getattr(self._props, name)

if __name__=="__main__":
  p = Properties()
  p.load(open('test2.properties'))
  p.list()
  print p
  print p.items()
  print p['name3']
  p['name3'] = 'changed = value'
  print p['name3']  
  p['new key'] = 'new value'
  p.store(open('test2.properties','w'))

当然,测试这个类你需要在程序目录下简历test2.properties 文件。才可以看到效果,基本可以达到用python 读写 properties 文件的效果.

补充知识:python修改配置文件某个字段

思路:要修改的文件filepath

在python中修改.properties文件的操作

将修改后的文件写入f2,删除filepath,将f2名字改为filepath,从而达到修改

修改的字段可以参数化,即下面出现的 lilei 可以参数化

imort os
tag=“jdbc.cubedata.username=”
midifyInfo=“jdbc.cubedata.username=lilei”
f1=filepath
f2=application.application
fileInfo=open(filepath)

在python中修改.properties文件的操作

以上这篇在python中修改.properties文件的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 动态获取当前运行的类名和函数名的方法
Apr 15 Python
在Python中使用PIL模块对图片进行高斯模糊处理的教程
May 05 Python
Python实现Sqlite将字段当做索引进行查询的方法
Jul 21 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
Dec 14 Python
详谈python3 numpy-loadtxt的编码问题
Apr 29 Python
Django框架之DRF 基于mixins来封装的视图详解
Jul 23 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
Aug 04 Python
TensorFlow打印输出tensor的值
Apr 19 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
May 12 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
Jun 30 Python
python cookie反爬处理的实现
Nov 01 Python
python 日志模块logging的使用场景及示例
Jan 04 Python
python3 配置logging日志类的操作
Apr 08 #Python
python3 logging日志封装实例
Apr 08 #Python
Django实现whoosh搜索引擎使用jieba分词
Apr 08 #Python
Python 输出详细的异常信息(traceback)方式
Apr 08 #Python
python上传时包含boundary时的解决方法
Apr 08 #Python
python MultipartEncoder传输zip文件实例
Apr 07 #Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 #Python
You might like
php从csv文件读取数据并输出到网页的方法
2015/03/14 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
PHP使用GD库输出汉字的方法【测试可用】
2016/11/10 PHP
thinkPHP实现多字段模糊匹配查询的方法
2016/12/01 PHP
PHP开发中csrf攻击的简单演示和防范
2017/05/07 PHP
php用wangeditor3实现图片上传功能
2019/08/22 PHP
php利用ZipArchive类操作文件的实例
2020/01/21 PHP
使用TextRange获取输入框中光标的位
2006/10/14 Javascript
Jquery 学习笔记(一)
2009/10/13 Javascript
JS中confirm,alert,prompt函数使用区别分析
2010/04/01 Javascript
extjs grid设置某列背景颜色和字体颜色的方法
2010/09/03 Javascript
JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))
2012/07/17 Javascript
node.js中的fs.symlinkSync方法使用说明
2014/12/15 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
2016/05/28 Javascript
JS实现鼠标框选效果完整实例
2016/06/20 Javascript
JavaScript实现前端实时搜索功能
2020/03/26 Javascript
详解vue + vuex + directives实现权限按钮的思路
2017/10/24 Javascript
js合并两个数组生成合并后的key:value数组
2018/05/09 Javascript
使用taro开发微信小程序遇到的坑总结
2019/04/08 Javascript
如何阻止移动端浏览器点击图片浏览
2020/08/29 Javascript
Python中对象迭代与反迭代的技巧总结
2016/09/17 Python
python中利用h5py模块读取h5文件中的主键方法
2018/06/05 Python
pandas计数 value_counts()的使用
2019/06/24 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
Java语言程序设计测试题改错题部分
2014/07/22 面试题
临床医学大学生求职信
2013/09/28 职场文书
学生学习总结的自我评价
2013/10/22 职场文书
素质拓展感言
2014/01/29 职场文书
小学毕业寄语大全
2014/04/03 职场文书
《池塘边的叫声》教学反思
2014/04/12 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
本科毕业生应聘自荐信范文
2014/06/26 职场文书
《大禹治水》教学反思
2016/02/22 职场文书
浅谈sql_@SelectProvider及使用注意说明
2021/08/04 Java/Android
《勇者辞职不干了》ED主题曲无字幕动画MV公开
2022/04/13 日漫