Generating data types automatically

T

Torsten Bronger

Hallöchen!

I have to generate a lot of data types (for ctypes by the way). An
example is

ViUInt32 = u_long
ViPUInt32 = POINTER(ViUInt32)
ViAUInt32 = ViPUInt32

Therefore, I defined functions that should make my life easier:

def generate_type_dublett(visa_type, ctypes_type):
visa_type_name = visa_type.__name__
exec visa_type_name + "=" + ctypes_type.__name__
exec "ViP" + visa_type_name[2:] + "=POINTER(" + visa_type_name + ")"

def generate_type_triplett(visa_type, ctypes_type):
generate_type_dublett(visa_type, ctypes_type)
visa_type_name = visa_type.__name__
exec "ViA" + visa_type_name[2:] + "=" + "ViP" + visa_type_name[2:]

generate_type_triplett(ViUInt32, c_ulong)


However, this doesn't work, probably because the defined type exist
only locally within the function.

What is a better (and working) method for this task?

Thank you!

Tschö,
Torsten.
 
T

Torsten Bronger

Hallöchen!

Torsten Bronger said:
I have to generate a lot of data types (for ctypes by the way).
An example is

ViUInt32 = u_long
ViPUInt32 = POINTER(ViUInt32)
ViAUInt32 = ViPUInt32

Therefore, I defined functions that should make my life easier:

[...]

However, this doesn't work, probably because the defined type
exist only locally within the function.

Okay this works:

def generate_type_dublett(visa_type, ctypes_type):
return visa_type + "=" + ctypes_type + ";" + \
"ViP" + visa_type[2:] + "=POINTER(" + visa_type + ")"

def generate_type_triplett(visa_type, ctypes_type):
return generate_type_dublett(visa_type, ctypes_type) + ";" + \
"ViA" + visa_type[2:] + "=" + "ViP" + visa_type[2:]

exec generate_type_triplett("ViUInt32", "c_ulong" )
....


Not very beautiful, though.

Tschö,
Torsten.
 
M

Michael Hoffman

Torsten said:
def generate_type_dublett(visa_type, ctypes_type):
visa_type_name = visa_type.__name__
exec visa_type_name + "=" + ctypes_type.__name__
exec "ViP" + visa_type_name[2:] + "=POINTER(" + visa_type_name + ")"

You shouldn't need to use exec for this, and it is best to avoid its use.

If you MUST do things this way, then you can add items to the globals()
dictionary. See the library reference for more details. It's probably
best to avoid globals() as well, although it's not as bad as exec/eval.

Personally, I think it would be better to define your types like this:

ViUInt32, ViPUInt32, ViAUInt32 = generate_type_triplet(u_long)

That way you will easily be able to find the initial definition of
the object by searching and replacing. You'll also have to jump through
fewer weird hoops to get the result you want.
 
S

Steven Bethard

Torsten said:
Okay this works:

def generate_type_dublett(visa_type, ctypes_type):
return visa_type + "=" + ctypes_type + ";" + \
"ViP" + visa_type[2:] + "=POINTER(" + visa_type + ")"

def generate_type_triplett(visa_type, ctypes_type):
return generate_type_dublett(visa_type, ctypes_type) + ";" + \
"ViA" + visa_type[2:] + "=" + "ViP" + visa_type[2:]

exec generate_type_triplett("ViUInt32", "c_ulong" )
...

Exec is nasty. Can you create a dict and use an update to globals instead?

py> def get_types(visa_type_name, ctypes_type):
.... pointer = ctypes.POINTER(ctypes_type)
.... return {'Vi%s' % visa_type_name:ctypes_type,
.... 'ViP%s' % visa_type_name:pointer,
.... 'ViA%s' % visa_type_name:pointer}
....
py> globals().update(get_types("UInt32", ctypes.c_ulong))
py> ViUInt32
<class 'ctypes.c_ulong'>
py> ViPUInt32
<class 'ctypes.LP_c_ulong'>
py> ViAUInt32
<class 'ctypes.LP_c_ulong'>

STeVe
 
T

Thomas Heller

Torsten Bronger said:
Hallöchen!

I have to generate a lot of data types (for ctypes by the way). An
example is

ViUInt32 = u_long
ViPUInt32 = POINTER(ViUInt32)
ViAUInt32 = ViPUInt32

Therefore, I defined functions that should make my life easier:

def generate_type_dublett(visa_type, ctypes_type):
visa_type_name = visa_type.__name__
exec visa_type_name + "=" + ctypes_type.__name__
exec "ViP" + visa_type_name[2:] + "=POINTER(" + visa_type_name + ")"

def generate_type_triplett(visa_type, ctypes_type):
generate_type_dublett(visa_type, ctypes_type)
visa_type_name = visa_type.__name__
exec "ViA" + visa_type_name[2:] + "=" + "ViP" + visa_type_name[2:]

generate_type_triplett(ViUInt32, c_ulong)


However, this doesn't work, probably because the defined type exist
only locally within the function.

Others have answered your question already, but I would like to note one
thing: The POINTER() function caches its results, so you could (and
should, imo) write 'POINTER(ViUInt32)' instead everywhere in your code.
Calling POINTER(ViUInt32) *allways* returns the same type.

Thomas
 
T

Torsten Bronger

Hallöchen!

Thomas Heller said:
Torsten Bronger said:
I have to generate a lot of data types (for ctypes by the way).
An example is

ViUInt32 = u_long
ViPUInt32 = POINTER(ViUInt32)
ViAUInt32 = ViPUInt32

[...]

Others have answered your question already, but I would like to
note one thing: The POINTER() function caches its results, so you
could (and should, imo) write 'POINTER(ViUInt32)' instead
everywhere in your code. Calling POINTER(ViUInt32) *allways*
returns the same type.

Actually I don't think that we will use them (ViP...) at all, since
we'll make use of "byref" whereever they occur in an args list.

But they are in the spec that we try to mimic, and as long as I
don't know for sure that nobody uses them, they don't hurt.

Tschö,
Torsten.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top