Question

I am trying to use properties and decorators in a class, but the problem I keep running into is getting the correct arguments, and the number of arguments.

class Xml(object):
    def __init__(self, data_dictionary=None):
        self.data_dictionary = data_dictionary

    def xml_wrapper(xml_msg):
        def wrap():
            return '<?xml version="1.0" encoding="UTF-8"?>\n'+xml_msg['name']
        return wrap


    @property
    @xml_wrapper
    def data_dictionary(self):
        return self._data_dictionary

    @data_dictionary.setter
    def data_dictionary(self, data):
        self._data_dictionary = data


if __name__ == '__main__':
    xml = Xml()
    xml.data_dictionary = {'name': 'name 1'}
    print xml.data_dictionary

The error I am getting is

 print xml.data_dictionary
TypeError: wrap() takes no arguments (1 given)

I am not sure why, I tried adding self to the xml_wrapper function but I still get an error.

Was it helpful?

Solution

In your code, the xml_wrapper is a decorator which takes a function, then wraps it with another function (wrap) and returns it. The function wrap does not take any argument(as in your code). But when you call xml.data_dictionary, python is implicitly passing the instance xml (known as self) which is causing the problem. May be this is what you want:

>>> class Xml(object):
        def __init__(self, data_dictionary=None):
            self.data_dictionary = data_dictionary

        def xml_wrapper(f):
            def wrap(*k,**kw):
                xml_msg = f(*k,**kw)
                return '<?xml version="1.0" encoding="UTF-8"?>\n'+xml_msg['name']
            return wrap


        @property
        @xml_wrapper
        def data_dictionary(self):
            return self._data_dictionary

        @data_dictionary.setter
        def data_dictionary(self, data):
            self._data_dictionary = data


>>> xml = Xml()
>>> xml.data_dictionary = {"name":"name 1"}
>>> print xml.data_dictionary
<?xml version="1.0" encoding="UTF-8"?>
name 1

This time xml_wrapper is taking a function (data_dictionary) then calls this function to get the xml_msg (inside wrap). wrap now takes arbitrarily many arguments and just passes those to original function (data_dictionary), takes the value, formats it, and returns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top