custom classes in sets

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vegetax

    #1

    custom classes in sets

    How can i make my custom class an element of a set?

    class Cfile:
    def __init__(s,path ): s.path = path

    def __eq__(s,other) :
    print 'inside equals'
    return not os.popen('cmp %s %s' % (s.path,other.p ath)).read()

    def __hashcode__(s) : return s.path.__hashco de__()

    the idea is that it accepts file paths and construct a set of unique
    files (the command "cmp" compares files byte by byte.),the files can
    have different paths but the same content

    but the method __eq__ is never called

  • Steven Bethard

    #2
    Re: custom classes in sets

    vegetax wrote:[color=blue]
    > How can i make my custom class an element of a set?
    >
    > class Cfile:
    > def __init__(s,path ): s.path = path
    >
    > def __eq__(s,other) :
    > print 'inside equals'
    > return not os.popen('cmp %s %s' % (s.path,other.p ath)).read()
    >
    > def __hashcode__(s) : return s.path.__hashco de__()
    >
    > the idea is that it accepts file paths and construct a set of unique
    > files (the command "cmp" compares files byte by byte.),the files can
    > have different paths but the same content
    >
    > but the method __eq__ is never called[/color]

    Seems to be called fine for me:

    py> class Cfile:
    .... def __eq__(self, other):
    .... print 'inside equals'
    .... return False
    .... def __hash__(self):
    .... return 0
    ....
    py> {Cfile():1, Cfile():2}
    inside equals
    {<__main__.Cfil e instance at 0x01166490>: 1, <__main__.Cfi le instance at
    0x01166760>: 2}

    Note that __eq__ won't be called if the hashes are different:

    py> class Cfile:
    .... hash = 0
    .... def __eq__(self, other):
    .... print 'inside equals'
    .... return False
    .... def __hash__(self):
    .... Cfile.hash += 1
    .... return Cfile.hash
    ....
    py> {Cfile():1, Cfile():2}
    {<__main__.Cfil e instance at 0x01166918>: 1, <__main__.Cfi le instance at
    0x011668A0>: 2}

    Steve

    Comment

    • vegetax

      #3
      Re: custom classes in sets

      Steven Bethard wrote:
      [color=blue]
      > vegetax wrote:[color=green]
      >> How can i make my custom class an element of a set?
      >>
      >> class Cfile:
      >> def __init__(s,path ): s.path = path
      >>
      >> def __eq__(s,other) :
      >> print 'inside equals'
      >> return not os.popen('cmp %s %s' % (s.path,other.p ath)).read()
      >>
      >> def __hashcode__(s) : return s.path.__hashco de__()
      >>
      >> the idea is that it accepts file paths and construct a set of unique
      >> files (the command "cmp" compares files byte by byte.),the files can
      >> have different paths but the same content
      >>
      >> but the method __eq__ is never called[/color]
      >
      > Seems to be called fine for me:
      >
      > py> class Cfile:
      > ... def __eq__(self, other):
      > ... print 'inside equals'
      > ... return False
      > ... def __hash__(self):
      > ... return 0
      > ...
      > py> {Cfile():1, Cfile():2}
      > inside equals
      > {<__main__.Cfil e instance at 0x01166490>: 1, <__main__.Cfi le instance at
      > 0x01166760>: 2}
      >
      > Note that __eq__ won't be called if the hashes are different:[/color]

      I just tried and it wont be called =(, so how can i generate a hash code for
      the CFile class? note that the comparitions(__ eq__) are done based on the
      contents of a file using the command 'cmp', i guess thats not posible but
      thanks.




      Comment

      • Carl Banks

        #4
        Re: custom classes in sets

        vegetax wrote:[color=blue]
        > Steven Bethard wrote:
        >[color=green]
        > > vegetax wrote:[color=darkred]
        > >> How can i make my custom class an element of a set?
        > >>
        > >> class Cfile:
        > >> def __init__(s,path ): s.path = path
        > >>
        > >> def __eq__(s,other) :
        > >> print 'inside equals'
        > >> return not os.popen('cmp %s %s' % (s.path,other.p ath)).read()
        > >>
        > >> def __hashcode__(s) : return s.path.__hashco de__()
        > >>
        > >> the idea is that it accepts file paths and construct a set of[/color][/color][/color]
        unique[color=blue][color=green][color=darkred]
        > >> files (the command "cmp" compares files byte by byte.),the files[/color][/color][/color]
        can[color=blue][color=green][color=darkred]
        > >> have different paths but the same content
        > >>
        > >> but the method __eq__ is never called[/color][/color][/color]

        [snip]
        [color=blue]
        > I just tried and it wont be called =(, so how can i generate a hash[/color]
        code for[color=blue]
        > the CFile class? note that the comparitions(__ eq__) are done based on[/color]
        the[color=blue]
        > contents of a file using the command 'cmp', i guess thats not posible[/color]
        but[color=blue]
        > thanks.[/color]


        Let me suggest that, if your idea is to get a set of files all with
        unique file contents, comparing a file byte-by-byte with each file
        already in the set is going to be absurdly inefficient.

        Instead, I recommend comparing md5 (or sha) digest. The idea is, you
        read in each file once, calculate an md5 digest, and compare the
        digests instead of the file contents.

        .. import md5
        ..
        .. class Cfile:
        .. def __init__(self,p ath):
        .. self.path = path
        .. self.md5 = md5.new().updat e(open(path).re ad()).digest()
        .. def __eq__(self,oth er):
        .. return self.md5 == other.md5
        .. def __hash__(self):
        .. return hash(self.md5)

        This is kind of hackish (not to mention untested). You would probably
        do better to mmap the file (see the mmap module) rather than read it.

        And, in case you're wondering: yes it is theoretically possible for
        different files to have the same md5. However, the chances are
        microscopic. (Incidentally, the SCons build system uses MD5 to decide
        if a file has been modified.)


        --
        CARL BANKS

        Comment

        Working...