How to access return values from COM function in IronPython? - com

I am trying to use IronPython to interact with a program which exposes COM API for many functions. The COM object handle is instantiated using following.
from System import Activator, Type
com_obj = Activator.CreateInstance(Type.GetTypeFromProgID("Test.Application"))
Most functions fall into the three following common prototypes categories:
function1(BSTR inpstr, [out] VARIANT * outstr)
function2(BSTR inpstr, [out] VARIANT_BOOL * outbool)
function3(BSTR inpstr, [out] SAFEARRAY ** outlist)
When using com_obj.function1, I create a return pointer using following, and the output is as expected.
>>> outstr = clr.Reference[object]()
>>> com_obj.function1('Test String', outstr)
>>> print(oustr.Value)
For com_obj.function2, I am also able to create return pointers prototype using clr.Reference to get a return value for VARIANT_BOOL*.
>>> outbool = clr.Reference[bool]()
>>> com_obj.function2('Test String', outbool)
>>> outbool.Value
However, for com_obj.function3, and I am unable to construct a return pointer for SAFEARRAY** to access the return values. I tried the following, but it did not work. Also, I need to convert the SAFEARRAY** data to python list for further processing.
>>> mylist = clr.Reference[Array[object]]()
>>> com_obj.function3('Test String', mylist)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Could not convert argument 1 for call to com_obj.function3
I think the last function (com_obj.function3) will not work unless I give proper pointers in IronPython describing SAFEARRAY** (array of strings?). I have struggled for weeks with this issue - and researching the internet turned up very little information - as IronPython is sparsely documented.
Any inputs on how I can get past these errors will be greatly appreciated.

Related

Getting UndefVarError: new not defined when trying to define a struct with an inner constructor in Julia

I'm new to Julia and trying out some code I copied from this article. It's supposed to be a way to do object-oriented programming (i.e. classes) in Julia:
using Lathe.stats: mean, std
struct NormalDistribution{P}
mu::Float64
sigma::Float64
pdf::P
end
function NormalDistribution(x::Array)
pdf(xt::Array) = [i = (i-μ) / σ for i in xt]
return new{typeof(pdf)}(mean(x), std(x), pdf)
end
x = [5, 10, 15, 20]
dist = NormalDistribution(x)
However, when I run this with Julia 1.1.1 in a Jupiter notebook I get this exception:
UndefVarError: new not defined
Stacktrace:
[1] NormalDistribution(::Array{Int64,1}) at ./In[1]:11
[2] top-level scope at In[1]:15
I found this documentation page on inner constructor methods which explains that they have
a special locally existent function called new that creates objects of the block's type.
(although the documentation for new linked above says it is a keyword).
It's possible I may have copied the code incorrectly but maybe someone could explain how to implement what the original author was proposing in the article. Also, I don't know how to debug in Julia yet so any pointers appreciated.
What the documentation page you linked to means to say is that the new keyword only exists within inner constructors (as opposed to outer constructors).
So either you go for an outer constructor, in which case you want to use the default constructor in order to actually create your new instance:
using Statistics
# First the type declaration, which comes with a default constructor
struct NormalDistribution{P}
mu::Float64
sigma::Float64
pdf::P
end
# Another outer constructor
function NormalDistribution(x::Array)
μ = mean(x)
σ = std(x)
pdf(xt::Array) = [(i-μ) / σ for i in xt]
# This is a call to the constructor that was created for you by default
return NormalDistribution(μ, σ, pdf)
end
julia> x = [5, 10, 15, 20]
4-element Array{Int64,1}:
5
10
15
20
julia> dist = NormalDistribution(x)
NormalDistribution{var"#pdf#2"{Float64,Float64}}(12.5, 6.454972243679028, var"#pdf#2"{Float64,Float64}(12.5, 6.454972243679028))
julia> dist.pdf([1, 2, 3])
3-element Array{Float64,1}:
-1.781572339255412
-1.626653005407115
-1.4717336715588185
Note that the definition of pdf in the original article is obviously problematic (if only because μ and σ are not defined). I tried to modify it so that it makes some sense
One possible issue with this is that anyone can define a NormalDistribution instance with an inconsistent state:
julia> NormalDistribution(0., 1., x->x+1)
NormalDistribution{var"#11#12"}(0.0, 1.0, var"#11#12"())
Which is why you might want to actually define an inner constructor, in which case Julia does not provide you with a default constructor but you get access to that special new function which creates objects of the type you're defining:
# A type declaration with an inner constructor
struct NormalDistribution2{P}
mu::Float64
sigma::Float64
pdf::P
# The inner constructor is defined inside the type declaration block
function NormalDistribution2(x::Array)
μ = mean(x)
σ = std(x)
pdf(xt::Array) = [(i-μ) / σ for i in xt]
# Use the `new` function to actually create the object
return new{typeof(pdf)}(μ, σ, pdf)
end
end
It behaves exactly in the same way as the struct with an outer constructor, except this time no default constructor is provided anymore:
julia> dist2 = NormalDistribution2(x)
NormalDistribution2{var"#pdf#5"{Float64,Float64}}(12.5, 6.454972243679028, var"#pdf#5"{Float64,Float64}(12.5, 6.454972243679028))
julia> dist2.pdf([1, 2, 3])
3-element Array{Float64,1}:
-1.781572339255412
-1.626653005407115
-1.4717336715588185
# No default constructor provided
julia> NormalDistribution2(0., 1., x->x+1)
ERROR: MethodError: no method matching NormalDistribution2(::Float64, ::Float64, ::var"#9#10")
Stacktrace:
[1] top-level scope at REPL[13]:1
An inner constructor has to be defined inside of the struct definition body; this is the only place where new has any special meaning. Your constructor method is outside of the struct definition where new is just a regular (undefined) name.
Ok. Looks like you were very confused. So that function is meant to be included as an inner constructor to the outer constructor before the end. The problem is the code is divided and built upon slowly across the article where only parts of the whole constructor are shown. If you are interested, and like my blog, I am about to post a video on outer constructors and inner constructors on my channel, https://youtube.com/playlist?list=PLCXbkShHt01seTlnlVg6O7f6jKGTguFi7 , it will be part 9 ( I am editing it now,) maybe watching this in video form will make it make more sense.
enter image description here

Access to **private** variables of a class in Python

I understand that Python does not explicitly support private variables in a class. However, please consider the following program:
class AClass(object):
def __init__(self, x):
self.__x = x
class BClass(object):
def __init__(self, x):
self.__x = x
# _____________________________________________________________________________
aClass = AClass(10)
bClass = BClass(10)
aClass.__x = 15
print (aClass.__x)
##bClass.__x = 20
print (bClass.__x)
The program above, will produce following error:
AttributeError: 'BClass' object has no attribute '__x'
But, if the second last line of code is uncommented, it will execute without an error.
If someone can please clarify what appears to be an inconsistency and if there is a PEP that explains this behaviour, I would appreciate a pointer to it.
Best regards.
BD
It's because variables starting with a dunder are name mangled to "protect" them. If you examine the dictionary of bClass, you'll see:
>>> print(bClass.__dict__)
{'_BClass__x': 10, '__x': 20}
The _BClass__x (I'll call this the object variable) was created by the object itself, hence its mangled name. The __x was created outside of the class(a) which is why it has a non-mangled name, and therefore why you can access it with just __x.
To access the object variable for both types, you can use:
print (aClass._AClass__x)
print (bClass._BClass__x)
But I'm not sure how reliable that is. I am sure that it's something you probably shouldn't be doing however, since it breaks encapsulation :-)
In fact, though I said the mangling was done by the object, I want to make sure you understand it's not done when an object is instantiated. The actual mangling happens when the code is compiled, which you can see if you disassemble:
>>> import dis
>>> dis.dis(AClass)
Disassembly of __init__:
3 0 LOAD_FAST 1 (x)
2 LOAD_FAST 0 (self)
4 STORE_ATTR 0 (_AClass__x)
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
The STORE_ATTR bytecode actually knows to use a mangled name.
(a) And it is very much distinct from the object variable, as you'll find to your distress when you later try to use __x within a member function and find it hasn't been changed by your code outside :-)

Static variable vs class variable vs instance variable vs local variable

Before posting, I read more than a half dozen posts in a search from this site (python variables class static instance local)
https://stackoverflow.com/search?q=python+variables+class+static+instance+local
I bookmarked several of the results for future studying, but none of them seemed to clarify to me if my thinking is right or wrong, so I feel I may be missing something about the basics (see below)...
Are the terms 'class variable' and 'static variable' referring to the same thing? After about three Google searches, reading through ~6 articles per search that I could understand, I've reached a conclusion that class and static variables are the same thing. But, since I'm just learning the fundamentals of Python and OOP, this conclusion may be wrong so I want to find any flaws in my reasoning before I continue learning with the wrong mindset. In the code below:
class Variables():
scVar = 3
def __init__(self, a, b):
self.iVar1 = a
self.iVar2 = b
def getLocalVar3(self):
localVar1 = 17
localVar2 = 100
localVar3 = localVar1 + localVar2
return localVar3
Is 'scVar' both a class variable and a static variable ('class' and 'static' variables being synonymns)?
The second question is to clarify my understanding of differentiating class variables, instance variables, and local variables. In the code above, I'm thinking that scVar is a class variable; iVar1 and iVar2 are instance variables; and localVar1, localVar2, and localVar3 are local variables. Is that correct to say, or is there something that I'm missing?
Thanks cirosantilli, That article that you linked to is one I haven't seen yet. I'm going to look that over. I wonder a bit about Python's point of vew that there's not a distinction between class variables and instance variables. Is this point of view one that I should try to understand correctly right up front, as a beginner, or should I just keep the idea in mind and not worry too much about reconciling my current point of view with that one until I become more experienced? That question probably seems overly vague, and dependent upon my current level of understanding Python. Mostly, I've been running commands on class examples similar to what is in the original post; predicting the output before I press the [enter] key and then studying the output when it's not what I predicted. From that, I'm starting to get some grasp of how things work in Python. Basically, I've just recently started getting a glimpse of how OO works in Python - inching forward, slowly but surely.
"However the above are just conventions: from the language point of view there is no distinction between class variables and instance variables." -- Just to help me understand this better, does the part, 'from the language point of view ...' sort of imply that the Python documentation explains this point of view somewhere within it? If so, I'll re-read through the docs and look specifically for this part, and try to conform my thinking process to it. "... between class variables and instance variables." So, even though there's the difference in the way that class and instance variables can be seen and accessed by 'classobj's and 'instance's, Python's
point of view is that there is no distinction between them? I'm going to keep this idea in mind during future reading so that I can maybe get rid of some confusion on my part. After I run the *.py in the original post, I get the following outputs in IDLE, using Python 2.7.x (only the last line of the traceback error is included, for better readability):
>>> Variables.scVar
3
>>> Variables.iVar1
AttributeError: class Variables has no attribute 'iVar1'
>>> instance = Variables(5, 15)
>>> instance
<__main__.Variables instance at 0x02A0F4E0>
>>> Variables
<class __main__.Variables at 0x02A0D650>
>>> instance.scVar
3
>>> instance.iVar1
5
>>> instance2 = Variables(25, 35)
>>> instance2.scVar
3
>>> Variables.scVar = Variables.scVar * 100
>>> Variables.scVar
300
>>> instance.scVar
300
>>> instance2.scVar
300
>>> instance.scVar = 9999
>>> Variables.scVar
300
>>> instance.scVar
9999
>>> instance2.scVar
300
>>> type(Variables)
<type 'classobj'>
>>> type(instance)
<type 'instance'>
"However the above are just conventions: from the language point of view there is no distinction between class variables and instance variables." -- By using the code from the original post, is there maybe a sequence of commands that illustrates this point? I don't doubt that you know what you're talking about; I just find it difficult to reconcile my current way of thinking with the above statement. But I get the feeling that if I can start to see the difference between the two perspectives, that something important will 'click'.
As an afterthought to the last few sentences, I might be on to seeing things more along the same lines as your statement about 'no distinction between class variables and instance variables', but only if my following assumption is accurate... From the code in the original post (class Variables - 12 lines), are there just the two scopes of global and local involved in that program? Since I've just started to form conclusions about how it all fits together, I think that my limited understanding of scope might be what keeps me from fully grasping the idea that there's no distinction between class variables and instance variables. The only thing I can seem to make of it now is that (only maybe) - 'Python has no distinction between class variables and instance variables; but the differences between global and local scope might make it appear to a novice that there is a distinction between these two types of variables. I don't know, does that statement identify a potential 'hang up' that I could be having about it?
"Everything is an object, including classes and integers:" -- I've read this numerous times. So much so that I take it to be a core belief to understanding OO and Python, but it's not a concept in which I fully realize the implications of yet (I think).
class Foo():
integer = 10
float = 6.37
string = 'hello'
boolean = True
idkyet = None
def __init__(self):
self.a = 'iv_a'
self.b = 'iv_b'
self.c = 'iv_c'
def Func(self):
self.g = 'g'
h = 'h'
i = 'i'
return 'g' + 'h' + 'i'
>>> Foo
<class __main__.Foo at 0x02A1D650>
>>> type(Foo.integer)
<type 'int'>
>>> type(Foo.float)
<type 'float'>
>>> type(Foo.string)
<type 'str'>
>>> type(Foo.boolean)
<type 'bool'>
>>> type(Foo.idkyet)
<type 'NoneType'>
>>> type(Foo)
<type 'classobj'>
>>> import os
>>> type(os.getcwd() + '\\Test.py')
<type 'str'>
>>> type(os)
<type 'module'>
>>> f = Foo()
>>> type(f)
<type 'instance'>
>>> type(f.Func)
<type 'instancemethod'>
>>> type(f.Func())
<type 'str'>
>>> f.Func
<bound method Foo.Func of <__main__.Foo instance at 0x02A25AF8>>
>>> Foo.Func
<unbound method Foo.Func>
>>> type(f.a)
<type 'str'>
>>> type(Foo.a)
AttributeError: class Foo has no attribute 'a'
>>> type(Foo.self.a)
AttributeError: class Foo has no attribute 'self'
When I was about half way through this response, leaving off with the 'class Foo():' code above and the commands ran on it below that, I hit a snag and couldn't quite continue with the other follow-up question that I barely had in mind. So, I stepped away from the problem for awhile and started to read that 'cafepy...' link that you posted (by Shalabh Chaturvedi). That's really interesting. I had seen excerpts from that before but I hadn't read the whole thing, but it seems much more understandable now than it would have been just a week ago. I think I will read the whole thing. Don't mind the last half of this post (after the '***') because I still can't pinpoint exactly what I was trying to ask. ...everything is an object...mainly just a difference in object types???... < That is the note that I had jotted down when I almost had in mind how to frame the last question, but it never came to fruition. I'll have to wait until something else 'clicks' and I can see again what I had in mind.
I'll also keep in mind to stop and re-read if I glance across anything related to 'MRO', bound and unbound methods... I have been picking up just a bit of those three terms lately, in a way that it feels like they won't be too far in the future of my learning process.
I believe that static and class variables are commonly used as synonyms.
What you say about the variables is correct from the convention point of view: this is how you should think about them most of the time.
However the above are just conventions: from the language point of view there is no distinction between class variables and instance variables.
Python is not like C++ or Java.
Everything is an object, including classes and integers:
class C(object): pass
print id(C)
C.a = 1
assert C.__dict__['a'] == 1
There is no clear distinction between methods and instance variables: they are just attributes of an object.
Therefore, there is no language level distinction between instance variables and class variables: they are just attributes of different objects:
instance variables are attributes of the object (self)
class variables are attributes of the Class object.
The real magic happens on the order that the . operator searches for attributes:
__dict__ of the object
__dict__ of the class of the object
MRO up to parent classes
You should read this great article before you get confused in the future.
Also beware of bound vs unbound methods.
EDIT: attempt to address further questions by the OP made in his post.
Wow that was large! I'll try to read everything, but for the future you should try to keep questions more concice. More code, less talk =). You'll get better answers.
should I just keep the idea in mind and not worry too much about reconciling my current point of view with that one until I become more experienced?": I do things.
I do as I feel necessary. When necessity calls, or I can't take magic behaviour anymore, I learn.
sort of imply that the Python documentation explains this point of view somewhere within it?
I don't know about the docs, but the language itself works that way.
Of course, the language was designed to give the impression that syntax works just like in C++ in the common cases, and it adds a thin layer of magic to classes to make it look like so.
But, since that is not how it truly works, you cannot account for all (useful) behaviour by thinking only in terms of C++ class syntax.
By using the code from the original post, is there maybe a sequence of commands that illustrates this point?
I'm not sure it can be illustrated in sequence of commands. The point is: classes are objects, and their attributes are searched by the dot . MRO on the same order as attributes of objects:
class C(object):
i_static = 0
def __init__(self):
self.i = 1
# i is in the __dict__ of object c
c = C()
assert c.__dict__['i'] == 1
assert c.i == 1
# dot finds i_static because MRO looks at class
assert c.__class__.__dict__['i_static'] == 0
assert c.i_static == 0
# i_static is in the __dict__ of object C
assert C.__dict__['i_static'] == 0
assert C.i_static == 0
# __eq__ is in the dict of type, which is the __class__ of C
# By MRO, __eq__ is found. `C,C` because of bound vs unbound.
assert C.__class__.__dict__['__eq__'](C,C)
assert C == C
are there just the two scopes of global and local involved in that program?
This is a point I don't know very clearly.
There is a no global scope in Python, only module level.
Then there is a new local scope inside functions.
The rest is how the . looks for attributes.
can't pinpoint exactly what I was trying to ask
Ask: can I find a difference in syntax between classes, integers or functions?
If you think you have found one, ask: hmmm, how can I make an object with certain attributes that behaves just like that thing which does not look like an object?
You should find an answer every time.
Example:
def f(): pass
class C(object): pass
AHA: f is different than c = C() because I can do f() but notc()`!
But then, no, it is just that the f.__class__.__dict__['__call__'] attribute is defined for f, and can be found via MRO.
But we can do that for c too:
class C(object):
def __call__(self): pass
and now we can do c().
So they were not different in that aspect.

Type checking in a dynamic language [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
As we all know, when we are using a dynamic language such as Python, we don't have to worry about Types. Because dynamic typing let us work without that concern. Even so, we can know the types of variables using the function type() (in Python). So my question is: What good do type checking in a dynamic language?
There are a few cases where type checking is something you want to do. Say, for example, you want to work with iterators, but not strings - this is a pretty common case. The best way to make that check is to type check if the item is a string:
if isinstance(someobj, str): # basestring in 2.x
...
We use isinstance() as it allows for subclasses as well as instances of the class itself. Checking directly using type() is pretty much universally a terrible idea, but type() does have other uses - sometimes you want to access the class of an instance for reasons other than type checking.
It's also worth noting that Python allows the definition of abstract base classes with a subclass hook - this allows isinstance() to do a kind of duck type check, where the class is checked for the relevant methods required. For example, if you want to check something is a Sequence, doing isinstance(obj, collections.Sequence) is not bad, as it's not actually type-checking in a traditional sense, it checks if the object has the functions necesary for the sequence interface (as defined in the docs).
In general, however, type checking should be avoided. In most cases, it's possible to simply try and do what you want, and then catch exceptions if the object can't do what it needs to. Python generally follows the rule of ask for forgiveness, not permission, so try it and gracefully handle errors, rather than checking beforehand.
In short: in a dynamic language, we rely on duck-typing. If an object can quack, we can assume it's a duck. 99% of the time, and object that can quack can be treated as a duck, so we are fine. However, in rare cases, another animal that can quack should not be treated as a duck. The only way we can distinguish between them is to type check, and that is OK. Type checking should not be used to check if our animal can quack, however, as we can just try and see (or, if we can't make it quack right now, but still need to operate dependent on it, check directly for the ability to quack, rather than checking for a type we know can quack).
In python everything is an "OBJECT", and inherits some "PROPERTIES" and "METHODS" that give it a uniqueness.
So, type is a "classification" of an object in terms of the "methods" and "properties" that charecterize it. In other words type checking gives us the utility of that object in terms of
"methods" and "attributes".
a python "list" is a sequence, a python "string" is a sequence but they have different attributes (one mutable and other immutable), following that they have unique methods to manupulate their structure. For example list can grow or diminish in size using 'append' and 'pop', for string they are forbidden. a string's representation may change with 'capitalize' or 'lower' for lists that may not work.
>>> i = "" # i declared string here
>>> i.append("K")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'append'
>>> i.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'pop'
similarly,
>>> a = [] # a declared a list here
>>> a.lower()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'lower'
>>> a.capitalize()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'capitalize'
Thanks for reading !
Consider a hierarchical data structure, where each node can be either a leaf, represented as a scalar object, or a subtree represented as an array. If you're writing a function to process all the leaves, it can use a recursive algorithm where it checks the type of each node; if it's an array it iterates over it and recurses, otherwise it processes the node.

How do I get a reference to an array back from VB when using IronPython?

I'm not a Python programmer, but I'm trying to get a simple script working using IronPython and VB.Net. I've gotten pretty far, but now I'm stuck on passing arguments by reference. I need to be able to get data back from the VB side into the Python side in the argument list (since Python returns tuples, but .Net doesn't). However, this code doesn't work, and I don't know why not.
Here is the python code:
def GetVoltages(voltages):
fixture.StartScan()
done=False
counter=0
while done == False:
fixture.GetNumDataPoints(num)
if num>=15:
done=True
else:
counter=counter+1
if counter>1000000:
break
if done == True:
fixture.GetDataPoints(num, voltages)
else:
log.WriteLine("Failed to read voltages.")
return done
buff = Array.CreateInstance(System.Double, 0)
if GetVoltages(buff):
log.WriteLine("Checking voltages.")
CheckVoltage(buff, 3, 22)
# do other stuff
fixture is a defined variable, and the function is called correctly, but num and voltages on the python side never change. Here is the function declarations on the VB side:
Public Function GetDataPoints(ByVal num As Integer, ByRef vals() As Double) As Boolean
Public Function GetNumDataPoints(ByRef num As Integer) As Boolean
I've found a couple old pages that give some hints, but I'm not seeing what the right answer is.
Basically, IronPython bundles ref and out parameters into the result as a tuple. That means you want something like:
success, num = fixture.GetNumDataPoints(num)
success, voltages = fixture.GetDataPoints(num, voltages)
There may be some interaction between ref and arrays, but this should work.