Python win32com.client Dispatch and Create Shorcut Methods - python

I want to ask few questions about win32com.client.
What does DisPatch do? It returns COMObject wscript.shell. What exactly is this?
shell = win32com.client.Dispatch("wscript.shell")
And why do we use it while creating shortcut.
shortcutcut = shell.CreateShortcut('shortcut.lnk')

win32com.client.Dispatch creates a ActiveX/COM object. The argument is the so-called program ID. Another example of program ID is "Excel.Application" which would be used to create an instance of Excel. In your case you are creating a wscript.shell object.
The program ID is mapped to a DLL on the system by the registry. The object is instantiated through a number of well-known export methods.
Apparently, one of the methods of a wscript.shell object is CreateShortcut. Why you are using a wscript.shell to do this, I can't say.

Related

Is there a way to allow for a win32com object to be modified by a COM object method?

In native visual basic within Excel, the expected behavior is
Dim AvayaReport As Object
Dim AvayaServer As Object
...
...
Set ReportInfo = AvayaServer.Reports.Reports("<Report Name>")
AvayaServer.Reports.CreateReport ReportInfo, AvayaReport
After the last line, the CreateReport method mutates AvayaReport to be a report object in this library. However, when I replicate this code within Python, AvayaReport does not get mutated.
import win32com.client
...
AvayaReport = win32com.client.dispatch("ACSREP.cvsReport")
...
ReportInfo = AvayaServer.Reports.Reports(r'<Report Name>")
AvayaServer.Reports.CreateReport(ReportInfo, AvayaReport)
I have tried to compare the behavior between the two environments and with the exception of this issue, the surrounding code is working as intended. However, this COM object has this weird implementation where it requires an empty object to be passed into it's arguments and it changes that object to reflect the created report, but I cannot figure out a way to make this work within Python.
Within VBA, the CreateReport definition is as follows:
Function CreateReport(oRepInfo, oReport, [sTimeZone as String = "default"]) As Boolean
Member of ACSTLG.cvsCatalog

python win32com excel >> ws.cells(1, 1).value does not work

i have used win32com.client to to something with excel.
so far, ".cells(1, 1).value" method succesfully read the value in row1, column1.
but from now, that code doesn't work.
it occurs error >>
'<win32com.gen_py.Microsoft Excel 16.0 Object Library._Worksheet instance at 0x2284591006720>' object has no attribute 'cells'
what is a problem?
xlsApp = win32com.client.GetActiveObject("Excel.Application")
wb = xlsApp.Workbooks(wb_name)
ws = wb.Worksheets(ws_name)
test = ws.cells(1, 1).value
print(test)
The method name is Cells() with an uppercase ‘C’ is the simple answer.
It is fair to ask: “If cells() worked before, why doesn’t it work now?”. IMHO it is a failing of win32com.
win32com will, if asked, generate a wrapper for COM objects (using a package called gen_py which creates a Python file for each object). If such a wrapper exists win32com will use it by default. This wrapper is case-sensitive. This is “early binding”.
If there is not a wrapper then calls like GetActiveObject() and Dispatch() will use “late binding” where win32com will try and call whatever method you want on the object (whether the method exists or not). The package takes whatever method you ask for and tries to get the ID of that function from the COM object via IDispatch.GetIdsOfNames(). Crucially, this lookup is case-INsensitive: using cells(),Cells() or even cElLs() will all work.
And this is the problem. The generated wrappers are stored in the user’s directory. Your code might have been happily using late-binding and cells(), but another programme may have created the wrapper at a later date. Now your code will see this wrapper and switch to early-binding and now cells() no longer works: you need to use Cells().
So, when using win32com it is always worth finding out the exact function name from the reference, eg from here

How to share python instance to c++?

I'm using python for my c++ program's sub script language.
I bind my c++ class to python to use it in python side.
This system must can share(pass) c++ instance to python.
And even Python (script side) can create new instance also it must be share by c++ side too.
But python(or..java, c#)'s class type is reference type.
#MyClass class has class type member test
data1 = MyClass()
data2 = MyClass()
#so data1's test will point data2.test object
data1.test = data2.test
So it will be work like a c++'s pointer.
But in c++, class is not reference type.
So assignment operation will call = operator.
if =operator will not overloaded then it will work value copy.
ClassInstance1 = ClassInstance2
Well If you create some objects in python, and share (pass) to c++ side.
like...
Character* pChara = PythonSideObjectToCpp("data1");
The data work rule is different between c++ and python.
So i think c++ can not 1:1 match with pythonlike above code.
It will need more interface about get, set or control python's reference type member.
How do you think about this?
I don't think that python instance can extract to c++ purely.
Well... but it can extract python instance's clone object.

How to change the string to class object in another file

I already use this function to change some string to class object.
But now I have defined a new module. How can I implement the same functionality?
def str2class(str):
return getattr(sys.modules[__name__], str)
I want to think some example, but it is hard to think. Anyway, the main problem is maybe the file path problem.
If you really need an example, the GitHub code is here.
The Chain.py file needs to perform an auto action mechanism. Now it fails.
New approach:
Now I put all files under one filefold, and it works, but if I use the modules concept, it fails. So if the problem is in a module file, how can I change the string object to relative class object?
Thanks for your help.
You can do this by accessing the namespace of the module directly:
import module
f = module.__dict__["func_name"]
# f is now a function and can be called:
f()
One of the greatest things about Python is that the internals are accessible to you, and that they fit the language paradigm. A name (of a variable, class, function, whatever) in a namespace is actually just a key in a dictionary that maps to that name's value.
If you're interested in what other language internals you can play with, try running dir() on things. You'd be surprised by the number of hidden methods available on most of the objects.
You probably should write this function like this:
def str2class(s):
return globals()[s]
It's really clearer and works even if __name__ is set to __main__.

Making something like plugin system

I want to make something like plugin system but can't make it working. To be specific I have some requirements.
I have main script who should search for other python scripts in ./plugins dir and load them.
This main script is searching for classes who inherits from Base using globals()
If I place these classes in the same main file it works very well but I can't get it worked as I want.
Is it possible to do this in Python?
I try to make some like this:
source: plugins/test.py
class SomeClass(Base):
def __init__(self):
self.name = "Name of plugin"
Main script just execute some methods on this class.
You could either import the python file dynamically or use the exec statement (make sure to define a context to execute in, otherwise the context you use the statement in will be used). Then use Base.__subclasses__, assuming Base being a new-style class, or call a function from the imported plugin module. In the latter case, you must provide a plugin-registration mechanism.
Use http://docs.python.org/2/library/imp.html#imp.load_module
For py3 I think there is importlib but I don't know how to use that one offhand.
Try importing the modules using imp -- imp.loadmodule will let you create namespace names dynamically if you need to. Then you can use inspect.getmembers() and inspect.is_class() to find the classes in your imported module (example code in this answer) to find all the clases defined there. Test those for being subclasses of your plugin.
...or, more pythonically, just use hasattr to find out if the imported classes 'quack like a duck' (ie, have the methods you expect from your plugin).
PS - I'm assuming you're asking for python 2.x. Good idea to tag the post with version # in future.

Categories

Resources