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

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

Related

Python. Adding custom methods to existing site-packages

I'm using openpyxl with python 2.7 to manipulate some workbooks. I've implemented my own methods for class Worksheet except they're not being found when I try to access them. I''m on windows and I've adding the following code to site-packages/openpyxl/worksheet/worksheet.py. Source code here.
class Worksheet(_WorkbookChild):
"""
Library defined methods here.
"""
#My Method.
def hello_world(self):
print "Hello from worksheet."
When I open up a workbook and try and call my function it raises an error for 'no attribute' even though it's been defined (properly?) under the scope of the class Worksheet.
import openpyxl
wb = openpyxl.load_workbook('helloworld.xlsx')
sheet = wb.get_active_sheet()
sheet.hello_world()
AttributeError: 'Worksheet' object has no attribute 'hello_world'
Do I need to do anything differently to update the existing library? I've deleted the .pyc, recompiled and am still getting the same error.
For anyone else who runs into this problem. The library was using 4 spaces for each indent while I was using a regular tab. The variation in indents caused the method to not be defined even though it appeared to be.

Prevent global variables of called submodules from being altered without changing the submodul itself?

I am trying to write some kind of wrapper for testing python module.
This wrapper simulates an environment and then starts other python module via execfile.
There are many python modules to be tested (>200).
Inside those modules there are some hard-coded variables that contain some absolute file-paths, that are not existing in my simulated environment (I also cannot create them). Those file-paths are paths to option files, that the script will read in. There is always exactly one option-file for each module and the file-path to thisoption files is always saved in the same global variable (What I mean: The variable name is the same in each module: optionFile).
optionFile = "Path to Option file"
My thought was, that I could maybe pre-set this global variable "optionFile" with an existing path before I execute the test-module. But of course this alone won't help, since the executed module will just overwrite "optionFile" with the hard-coded value when it is executed.
I wondered if there might be a way to overwrite the __setattr__ function of the globals-object, so that it will do nothing for certain variable names, but I was not successful with my tries. Do you think this could work and have any suggestions?
Based on the first impressions we got here it seems to be not possible to alter the __setattr__ of the globals object (though I don't understand why not...)
So the answer seems to be "No".
EDIT:
The reason, why this does not work here is, that there is no global "globals "-object. Instead each module has its "personal" namespace with its own global variables. This namespace is created once the module is loaded. It is for sure possible to alter that global namespace - but only after the module has already been loaded (which does not help in my application scenario). Thanks to BrenBarn for the clarification.
END OF EDIT
A workaround for my specific described problem would be to alter Python's built-in open-function instead.
# Keep original pointer to the actual Open-function
realOpen = open
# Overwrite the name of the Open-function to implement own logic
def open(filename, mode='r'):
if filename.endswith(".opt"):
print "Rerouting opening command"
realOpen("myCentralOptionFile.opt","r")
else:
realOpen(filename,mode)
Attention: This workaround has nothing to do with the title anymore.

Python win32com.client Dispatch and Create Shorcut Methods

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.

In Python, how to access a function-internal inline function (intention: to unit test)?

I have a body of python code that contains inline functions within functions. I'd like to unit test the make_exciting inner function, so I'm trying to figure out how to invoke it directly.
def say_something_exciting(name, phrase):
def make_exciting(phrase):
return phrase + "!"
return "%s says '%s'" % (name, make_exciting(phrase))
Function say_something_exciting is written at the top level of a .py file, and is not inside a class. The py file is in the org.something module. Tried:
Invoking the function directly via org.something.say_something_exciting.make_exciting("Hello") - error: 'function' object has no attribute 'make_exciting'
Inspecting dir(org.something.say_something_exciting) and org.something.say_something_exciting.__dict__ for any paths to traverse, didn't see make_exciting anywhere.
internal_function = org.something.say_something_exciting.__dict__.get('make_exciting'), but internal_function is None.
How can I access (unit test) this inner function? This may suggest what I'm asking isn't possible. I'm generally familiar with unit testing and how to use the unittest module; accessing the function is the problem. If it's not possible, how should I re-write this code to support testing (if other than promote the inner function to a top-level function)?. Thanks!
UPDATE: In Java I often give class methods default/package visibility so they're less visible but still accessible to unit tests, looking for a python equivalent.
I don't think you can.
You'll need to return the inner function, or bind it elsewhere. It gets ugly though. You can bind the declared function to somewhere else, from inside the function:
import testmodule
testmodule.testfunc = make_exciting
Or you can return it, for example when a keyword-argument is given, such as export=True.

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__.

Categories

Resources