简体   繁体   中英

TypeError: function()) takes exactly X arguments (1 given) with @property decorator

So I've looked around and read many postings covering the TypeError: message, where it "takes exactly X arguments but only 1 is given".

I know about self . I don't think I have an issue understanding self . Regardless, I was trying to to create a class with some properties and as long as I have @property in front of my function hwaddr , I get the following error:

Traceback (most recent call last):
  File line 24, in <module>
    db.hwaddr("aaa", "bbbb")
TypeError: hwaddr() takes exactly 3 arguments (1 given)

Here is the code. Why is @property messing me up? I take it out, and the code works as expected:

#!/usr/bin/env python2.7

class Database:
    """An instance of our Mongo systems database"""

    @classmethod
    def __init__(self):
        pass

    @property
    def hwaddr(self, host, interface):

        results = [ host, interface ]
        return results

db = Database()
print db.hwaddr("aaa", "bbbb"

Process finished with exit code 1

With it gone, the output is:

File
['aaa', 'bbbb']

Process finished with exit code 0

Properties are used as syntactical sugar getters. So they expect that you only pass self . It would basically shorten:

print db.hwaddr()

to:

print db.hwaddr

There is no need to use a property here as you pass two arguments in.

Basically, what Dair said: properties don't take parameters, that's what methods are for.

Typically, you will want to use properties in the following scenarios:

  • To provide read-only access to an internal attribute
  • To implement a calculated field
  • To provide read/write access to an attribute, but control what happens when it is set

So the question would be, what does hwaddr do, and does it match any of those use cases? And what exactly are host and interface? What I think you want to do is this:

#!/usr/bin/env python2.7

class Database:
    """An instance of our Mongo systems database"""

    def __init__(self, host, interface):
        self._host = host
        self._interface = interface

    @property
    def host(self):
        return self._host

    @property
    def interface(self):
        return self._interface

    @property
    def hwaddr(self):
        return self._host, self._interface

db = Database("my_host", "my_interface")
print db.host
print db.interface
print db.hwaddr

Here, your Database class will have host and interface read-only properties, that can only be set when instantiating the class. A third property, hwaddr , will produce a tuple with the database full address, which may be convenient in some cases.

Also, note that I removed the classmethod decorator in init ; constructors should be instance methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM