I'm working with the python-docx
library from a forked version, and I'm having an issue with editing the elements list as it is defined as a property.
# docx.document.Document
@property
def elements(self):
return self._body.elements
I tried to go with the solution mentioned here but the error AtributeError: can't set attribute
still popping out.
Next thing I tried is adding the setter
to the attribute derived from self._body
and editing the code:
# docx.blkcntnr.BlockItemContainer
@property
def elements(self):
"""
A list containing the elements in this container (paragraph and tables), in document order.
"""
return [element(item,self.part) for item in self._element.getchildren()]
I've tried to add the setter
in both levels but ended up again with the error AtributeError: can't set attribute
The setter
I wrote:
@elements.setter
def elements(self, value):
return value
The implementation I tired:
elements_list = docx__document.elements
elem_list = []
docx__document.elements = elements_list = elem_list
The main problem with that code is docx__document.elements
still contains all the elements that are supposed to have been deleted!
Editing the library was like this:
# Inside docx.document.Document
@property
def elements(self):
return self._body.elements
@elements.setter
def elements(self, value=None):
self._body.elements = value
gc.collect()
return value
The other part:
# Inside docx.blkcntnr.BlockItemContainer
@property
def elements(self):
"""
A list containing the elements in this container (paragraph and tables), in document order.
"""
return [element(item,self.part) for item in self._element.getchildren()]
@elements.setter
def elements(self, value):
"""
A list containing the elements in this container (paragraph and tables), in document order.
"""
return value
Related question [Update]
If I did add a setter
for this property
:
# docx.document.Document
@property
def elements(self):
return self._body.elements
Should I add also a setter
for the property
:
# docx.blkcntnr.BlockItemContainer
@property
def elements(self):
"""
A list containing the elements in this container (paragraph and tables), in document order.
"""
return [element(item,self.part) for item in self._element.getchildren()]
Because the value of document.elemetns
is actually the value from document._body.elements
, am I right?
Any help would appreciate it!
CodePudding user response:
First a word of warning: if you edit a library, those changes will be wiped away if/when you upgrade the library.
While your question is still not reproducible, I can see now what the problem is.
Setters need to mutate some kind of state to be useful. They don't return values.
# Inside docx.document.Document
@elements.setter
def elements(self, value):
self._body.elements = value
# Inside docx.blkcntnr.BlockItemContainer
@elements.setter
def elements(self, value):
# FIXME
Unfortunately, I haven't been able to figure out how to implement docx.blkcntnr.BlockItemContainer.elements.setter
in a way that neatly replaces the XML tree.
Since it looks like you want to use it to wipe a document clear, why not simply instantiate a new Document
instead, like so?
docx__document = docx.Document()