scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.45k stars 528 forks source link

Freature-Request: Access SlideShapes items by name #309

Open timhoffm opened 7 years ago

timhoffm commented 7 years ago

SlideShapes items can currently be accessed by index: slide.shapes[2]

It should be possible to access them by name as well: slide.shapes['myShape']

This behavior is in accordance with the Microsoft VBA API: From https://msdn.microsoft.com/VBA/PowerPoint-VBA/articles/shapes-object-powerpoint

Use Shapes (index), where index is the shape's name or index number, to return a single Shape object.

If there is interest, I can work on a pull request.

scanny commented 7 years ago

I think I'd be more inclined to do this using a method rather than overloading indexed access (square brackets). Maybe Shapes.get_by_name(shape_name, default=KeyError).

The behavior would be:

Another benefit is it allows room for other search methods, in particular Shapes.get_by_id(shape_id, default=KeyError), which I happen to need myself, which typically increases the chances of a successful implementation and merge :)

timhoffm commented 7 years ago

Thanks for the reply.

I still favor slide.shapes['myShape'] for this particular case because of its simplicity of and the similarity to VBA Slide.Shapes("myShape"). Also, the overloading of item access for indices and names is not uncommon in Python (e.g. pandas.Series or structured numpy arrays). It's what I would be naturally expecting.

Nevertheless, get_by_name() and get_by_id() would be ok as well, in resemblence to the dict.get() API. (By me, they could even coexist with name-index access.)

if shape with matching name is found, the first match is returned

In a quick check, it seems that VBA Slide.Shapes("myShape") returns the last match instead of the first. You might want to consider using the VBA convention as well. Whatever the choice (and possible deviations from VBA behavior), it should be documented.

Any interest in a pull request, or will you work on this yourself? If I should provide a pull request, please give your final design choices,