suppose i have built a VObject called vobj (e.g., built  via vobject.readComponents(vcfStr)) and want to add a new key:value pair to it:
  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)
all the extra prints and the try:except are because i can't
make it work!  here's the output produced:
  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)
i have three specific questions:
VObject makes use of
object.attribute"dot" notation, and the only way i've found to handle arbitrary key names is usingeval(). there must be a more pythonic way?evaluation of the first statement
stmnt1works, and changesvobjas expected, producing an unbound slot forBDAY. butstmnt2fails with bad syntax and i don't know why.i have also tried
stmnt2 = "vobj.%s.value = ['%s']" % (k,v), making the value a list, because of the two alternatives on the VObject README:j.email.value = '[email protected]' ... j.org.value = ['Open Source Applications Foundation']does it matter whether a string atom or list is used?
                        
I tried to simplify your code, and ended up with:
which produced:
which seems to be what was expected.
Question 1 There's not generally a need for arbitrary names in vObjects, because the specifications dictate what values are required, and they're all handled by the vobject code.
A common pattern when adding a value is to save a reference to the added attribute, and access it directly, like:
or, just do it inline:
Or you can access it directly:
Question 2 The problem here is nothing to do with vobject, but rather with Python. In Python,
evalonly works for expressions. To dynamically compile and execute a statement (like yourstmnt2), you need to useexec.If you change
to
your example code sets the BDAY property without an exception.
See What's the difference between eval, exec, and compile? for a full explanation.
Question 3 Yes, it matters. The type of values of the various attributes of a vObject are determined by the specifications. Some have a single value, others are (optionally) a set of values. vobject doesn't enforce this, currently.