如何使用VObject操作VCF触点?

问题描述 投票:0回答:1

假设我已经构建了一个名为

vobj
的 VObject(例如,通过
vobject.readComponents(vcfStr)
构建)并且想要向其添加一个新的键:值对:

  print('k=%s v=%s' % (k,v))
  try:
      stmnt1 = "vobj.add('%s')" % (k)
      print('stmnt1:"%s"' % stmnt1)
      eval(stmnt1)

      print('vobj after add\n'+20*'#'+'\n')
      vobj.prettyPrint()
      stmnt2 = "vobj.%s.value = '%s'" % (k,v)
      print('\n'+20*'#'+('\nstmnt2:"%s"' % stmnt2))
      eval(stmnt2)
  except Exception as e:
      print('wazzup?!',e)

所有额外的印刷品和

try:except
都是因为我不能 让它起作用!这是产生的输出:

  k=bday v=1931-02-10
  stmnt1:"vobj.add('bday')"
  vobj after add
  ####################

   VCARD
      VERSION: 3.0
      PRODID: -//Apple Inc.//Mac OS X 10.12.3//EN
      N:  Foo Bar 
      FN: Foo Bar
      EMAIL: [email protected]
      params for  EMAIL:
         TYPE ['INTERNET', 'WORK', 'pref']
      ...
      BDAY: 

  ####################
  stmnt2:"vobj.bday.value = '1931-02-10'"
  wazzup?! invalid syntax (<string>, line 1)

我有三个具体问题:

  1. VObject 使用

    object.attribute
    “点”表示法, 我发现处理任意键名的唯一方法 正在使用
    eval()
    。一定有更Pythonic的方式吗?

  2. 第一个语句的评估

    stmnt1
    有效,并且发生了变化
    vobj
    正如预期的那样,为
    BDAY
    生成一个未绑定的槽。 但是
    stmnt2
    由于语法错误而失败,我不知道为什么。

  3. 我也尝试过

    stmnt2 = "vobj.%s.value = ['%s']" %
    (k,v)
    ,将值设为列表,因为这两个 VObject 自述文件中的替代方案:

     j.email.value = '[email protected]'
     ...
     j.org.value = ['Open Source Applications Foundation']
    

    使用字符串原子还是列表有关系吗?

python vobject
1个回答
0
投票

我尝试简化你的代码,最终得到:

import vobject

s = 'BEGIN:VCARD\r\nFN:John Smith\r\nN:Smith;John;;;\r\nEND:VCARD'
vobj = vobject.readOne(s)

vobj.add('bday')
vobj.prettyPrint()

vobj.bday.value = '1931-02-10'
vobj.prettyPrint()

产生:

> python test.py
VCARD
   FN: John Smith
   N:  John  Smith 
  BDAY: 
VCARD
   FN: John Smith
   N:  John  Smith 
   BDAY: 1931-02-10
>

这似乎是预期的。

问题1 vObject 中通常不需要任意名称,因为规范规定了所需的值,并且它们全部由 vobject 代码处理。

添加值时的常见模式是保存对所添加属性的引用,并直接访问它,例如:

notes = vobj.add("NOTES")
notes.value = "The content of my notes"

或者,直接内联执行:

vobj.add("NOTES").value = "Notes in one line"

或者您可以直接访问:

vobj.notes.value = "New notes content"

问题2 这里的问题与vobject无关,而是与Python有关。在 Python 中,

eval
仅适用于 表达式。要动态编译和执行语句(如您的
stmnt2
),您需要使用
exec

如果你改变

eval(stmnt2)

exec(stmnt2)

您的示例代码毫无例外地设置了 BDAY 属性。

请参阅 eval、exec 和compile 之间有什么区别? 以获取完整说明。

问题3 是的,这很重要。 vObject 的各种属性的值的类型由规范确定。有些具有单个值,其他则(可选)是一组值。 vobject 目前不强制执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.