0

Setup:

  • Python 3.6
  • python-pptx
  • openpyxl
  • openpyxl-image-loader

My goal:
To extend the Presentation class to include more functions to build unique PPT slides I do not wish to override any previous __init__().

My Progress so far:
I use type() to see what class I should extend.

from pptx import Presentation
prs=Presentation('template.pptx')
print(type(prs))
>><class 'pptx.presentation.Presentation'>

I then created a new class that inherits pptx.presentation.Presentation:

class Build_ppt(pptx.presentation.Presentation):

   def build_cover(self,i,ws):
   #i : index
   #ws: is an openpyxl instance
       pass

I then try to call the new Build_ppt class similar to how you would Presentation:

prs=Build_ppt('template.pptx')

I get the following errors:

TypeError: __init__() missing 1 required positional argument: 'part'

or sometimes it does go through but the super class does not have the proper arguments passed in.

martineau
  • 119,623
  • 25
  • 170
  • 301
Gzain_AS
  • 1
  • 1
  • It's fairly common to not be able to extend classes in modules, especially those written in other languages like C/C++. One workaround it to define a "proxy" class that *has* an instance of the class to be extended in it rather than being derived from one. The methods of the proxy class delegate calls to this instance possibly with so pre- and/or post-processing. There's a trivial example of one in [my answer](https://stackoverflow.com/a/11380084/355230) to an different question. Also see Wikipedia's [Proxy pattern](https://en.wikipedia.org/wiki/Proxy_pattern) article. – martineau Jul 16 '21 at 21:23

1 Answers1

0

The Presentation object you get with from pptx import Presentation is not the same as pptx.presentation.Presentation.

If you look in pptx/__init__.py you can see from pptx.api import Presentation. This is what establishes what you reference as pptx.Presentation. https://github.com/scanny/python-pptx/blob/master/pptx/__init__.py#L14

If you look in pptx/api.py you can see that Presentation is a function that does the needful to open a presentation (.pptx) document, create a pptx.presentation.Presentation object with it, and return that object. https://github.com/scanny/python-pptx/blob/master/pptx/api.py#L18

So pptx.Presentation looks and acts like a class, but it isn't. If you want your own version of pptx.Presentation you'll have to model it after the pptx.api.Presentation function rather than the object it returns.

However, I don't recommend you do that. There are a lot of complexities and you'll be completely on your own because everything you do from there on is in "off-label" territory and not using the published interfaces.

What you can do instead is compose a Presentation object and then manipulate it with the class that "contains" it.

The other alternative is to fork python-pptx and extend it to suit your purposes. Of course you're on your own that way as well.

A third alternative is to use python-pptx as it is for whatever you can and write "extension" functions that do things python-pptx can't directly do for you. This is a very common approach and one I use myself fairly often.

scanny
  • 26,423
  • 5
  • 54
  • 80