0

给定一个描述 object.attribute 的 Python 字符串,我如何将属性的命名空间与属性分开?

期望的例子:

ns_attr_split("obj.attr") => ("obj", "attr")
ns_attr_split("obj.arr[0]") => ("obj", "arr[0]")
ns_attr_split("obj.dict['key']") => ("obj", "dict['key']")
ns_attr_split("mod.obj.attr") => ("mod.obj", "attr")
ns_attr_split("obj.dict['key.word']") => ("obj", "dict['key.word']")

注意:我知道编写自己的字符串解析器是一种选择,但我正在寻找一种更优雅的解决方案。滚动我自己的字符串解析器并不像 '.' 上的 rsplit 那样简单。因为上面列出的最后一个选项,给定的关键字可能包含命名空间分隔符。

4

3 回答 3

1

我最近发现了用于标记 python 源代码的标记化库。使用这个库我想出了这个小代码片段:

import tokenize
import StringIO

def ns_attr_split(s):
  arr = []
  last_delim = -1
  cnt = 0

  # Tokenize the expression, tracking the last namespace
  # delimiter index in last_delim
  str_io = StringIO.StringIO(s)
  for i in tokenize.generate_tokens(str_io.readline):
    arr.append(i[1])
    if i[1] == '.':
      last_delim = cnt
    cnt = cnt + 1

  # Join the namespace parts into a string
  ns = ""
  for i in range(0,last_delim):
    ns = ns + arr[i]

  # Join the attr parts into a string
  attr = ""
  for i in range(last_delim + 1, len(arr)):
    attr = attr + arr[i]

  return (ns, attr)

这也适用于中间索引/键。(即“mod.ns[3].obj.dict['key']”)

于 2013-09-23T01:57:25.113 回答
0

一个有趣的小正则表达式问题...

此代码适用于您使用 Python 2.6 提供的所有示例,并假设您没有任何中间索引/键访问(例如“obj['foo'].baz”):

import re
ns_attr_split = lambda s: re.match(r"((?:\w+\.)*\w+)\.(.+)", s).groups()
于 2013-09-23T01:31:09.840 回答
0

假设命名空间始终是字母数字,您可以先拆分 on /[^a-zA-Z.]/,然后拆分rspliton .

>>> import re
>>> ns_attr_split = lambda s: re.split("[^a-zA-Z.]", s, 1)[0].rsplit('.')
>>> ns_attr_split("obj.dict['key.word']") 
['obj', 'dict']

显然这不是你想要的……但摆弄是直截了当的。

于 2013-09-23T01:00:08.180 回答