0

I have this class and use it in the manner shown in __main__:

class User:

  def __init__(self, username, password, isActive):
    self.username = username
    self.password = password
    self.isActive = isActive

  def __str__(self):
    return str(self.__dict__)

  def __eq__(self, other):
      return (isinstance(other, self.__class__)
          and self.__dict__ == other.__dict__)

  def __ne__(self, other):
      return not self.__eq__(other)

  def __hash__(self):
    # Error here: TypeError: tuple() takes at most 1 argument (3 given)
    return hash(tuple(self.username, self.password, self.isActive))

if __name__ == "__main__":
  s1 = set()
  s2 = set()

  # These two instances should be equivalent
  s1.add(User("bob", "12hhjka9#", True))
  s2.add(User("bob", "12hhjka9#", True))

  # These two instances should not be equivalent
  s1.add(User("alice", "12hhjka9#", False))
  s1.add(User("alice", "12hhjka9#", True))

  for user in s1.symmetric_difference(s2):
    print str(user)
  print "done"

Instances of this class are never changed after construction, so it is safe to use instance variables in the hash implementation. I get this error during execution:

# Error here: TypeError: tuple() takes at most 1 argument (3 given)

I've tried other variations of __hash__, but can't get it right. Help!

1
  • If you remove the word tuple, you will get a tuple automatically. Commented Aug 13, 2014 at 15:17

2 Answers 2

2

You are simply using the tuple() function incorrectly; it is not even needed here.

The following will work:

def __hash__(self):
    return hash((self.username, self.password, self.isActive))

The tuple() function can only take one argument, but you passed in 3. You'd pass in another iterable:

return hash(tuple([self.username, self.password, self.isActive]))

but using just parentheses ((...)) to group the values produces a single tuple too.

Sign up to request clarification or add additional context in comments.

Comments

0

You should consider using a namedtuple instead of your own custom class. This is built in to Python's standard library.

from collections import namedtuple
User = namedtuple('User', ('username', 'password', 'isActive'))

Named tuples are subclasses of tuple, so hashes and equalities are already taken care of.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.