UnboundMethodType and MethodType

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Schüle Daniel

    UnboundMethodType and MethodType

    Hello all,
    [color=blue][color=green][color=darkred]
    >>> class Q:[/color][/color][/color]
    .... def bar(self):
    .... pass
    ....[color=blue][color=green][color=darkred]
    >>> import types
    >>> types.UnboundMe thodType is types.MethodTyp e[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>>
    >>> type(Q.bar)[/color][/color][/color]
    <type 'instancemethod '>[color=blue][color=green][color=darkred]
    >>>
    >>> q = Q()
    >>> type(q.bar)[/color][/color][/color]
    <type 'instancemethod '>[color=blue][color=green][color=darkred]
    >>>
    >>> type(q.bar) is types.UnboundMe thodType[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> q.bar[/color][/color][/color]
    <bound method Q.bar of <__main__.Q instance at 0x4042756c>>[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    I think is not very consistent
    notice q.bar is bounded although type(q.bar)
    says it's types.Unbounded MethodType
    what do you think?

    Regard, Daniel

  • Kirk McDonald

    #2
    Re: UnboundMethodTy pe and MethodType

    Schüle Daniel wrote:[color=blue]
    > Hello all,
    >[color=green][color=darkred]
    > >>> class Q:[/color][/color]
    > ... def bar(self):
    > ... pass
    > ...[color=green][color=darkred]
    > >>> import types
    > >>> types.UnboundMe thodType is types.MethodTyp e[/color][/color]
    > True[color=green][color=darkred]
    > >>>
    > >>> type(Q.bar)[/color][/color]
    > <type 'instancemethod '>[color=green][color=darkred]
    > >>>
    > >>> q = Q()
    > >>> type(q.bar)[/color][/color]
    > <type 'instancemethod '>[color=green][color=darkred]
    > >>>
    > >>> type(q.bar) is types.UnboundMe thodType[/color][/color]
    > True[color=green][color=darkred]
    > >>> q.bar[/color][/color]
    > <bound method Q.bar of <__main__.Q instance at 0x4042756c>>[color=green][color=darkred]
    > >>>[/color][/color]
    >
    > I think is not very consistent
    > notice q.bar is bounded although type(q.bar)
    > says it's types.Unbounded MethodType
    > what do you think?
    >
    > Regard, Daniel
    >[/color]

    I think it's perfectly consistent:
    [color=blue][color=green][color=darkred]
    >>> class B(object):[/color][/color][/color]
    .... def bar(self): pass
    ....[color=blue][color=green][color=darkred]
    >>> B.bar[/color][/color][/color]
    <unbound method B.bar>[color=blue][color=green][color=darkred]
    >>> type(B.bar)[/color][/color][/color]
    <type 'instancemethod '>[color=blue][color=green][color=darkred]
    >>> b = B()
    >>> b.bar[/color][/color][/color]
    <bound method B.bar of <__main__.B object at 0xb7bd544c>>[color=blue][color=green][color=darkred]
    >>> type(b.bar)[/color][/color][/color]
    <type 'instancemethod '>[color=blue][color=green][color=darkred]
    >>> id(B.bar)[/color][/color][/color]
    -1211888788[color=blue][color=green][color=darkred]
    >>> id(b.bar)[/color][/color][/color]
    -1211888788

    It's the same function, whether it's bound or not. Thus, it should
    always have the same type. It's simply called in different ways. You can
    just as easily say:
    [color=blue][color=green][color=darkred]
    >>> B.bar(b)[/color][/color][/color]

    As:
    [color=blue][color=green][color=darkred]
    >>> b.bar()[/color][/color][/color]

    -Kirk McDonald

    Comment

    • Kent Johnson

      #3
      Re: UnboundMethodTy pe and MethodType

      Kirk McDonald wrote:
      [color=blue]
      > I think it's perfectly consistent:
      >[color=green][color=darkred]
      > >>> class B(object):[/color][/color]
      > ... def bar(self): pass
      > ...[color=green][color=darkred]
      > >>> B.bar[/color][/color]
      > <unbound method B.bar>[color=green][color=darkred]
      > >>> type(B.bar)[/color][/color]
      > <type 'instancemethod '>[color=green][color=darkred]
      > >>> b = B()
      > >>> b.bar[/color][/color]
      > <bound method B.bar of <__main__.B object at 0xb7bd544c>>[color=green][color=darkred]
      > >>> type(b.bar)[/color][/color]
      > <type 'instancemethod '>[color=green][color=darkred]
      > >>> id(B.bar)[/color][/color]
      > -1211888788[color=green][color=darkred]
      > >>> id(b.bar)[/color][/color]
      > -1211888788
      >
      > It's the same function, whether it's bound or not. Thus, it should
      > always have the same type.[/color]

      No, it's not the same function. You got the same id because you didn't
      bind B.bar and b.bar to anything so the id was reused.
      [color=blue][color=green][color=darkred]
      >>> class B(object):[/color][/color][/color]
      ... def bar(self): pass
      ...[color=blue][color=green][color=darkred]
      >>> Bbar = B.bar
      >>> bbar = B().bar
      >>> Bbar[/color][/color][/color]
      <unbound method B.bar>[color=blue][color=green][color=darkred]
      >>> bbar[/color][/color][/color]
      <bound method B.bar of <__main__.B object at 0x008759B0>>[color=blue][color=green][color=darkred]
      >>> id(Bbar)[/color][/color][/color]
      10751312[color=blue][color=green][color=darkred]
      >>> id(bbar)[/color][/color][/color]
      10736624[color=blue][color=green][color=darkred]
      >>> Bbar is bbar[/color][/color][/color]
      False

      Kent

      Comment

      • Scott David Daniels

        #4
        Re: UnboundMethodTy pe and MethodType

        Kent Johnson wrote:[color=blue]
        > Kirk McDonald wrote:[/color]
        ....[color=blue][color=green][color=darkred]
        >> >>> id(B.bar)[/color]
        >> -1211888788[color=darkred]
        >> >>> id(b.bar)[/color]
        >> -1211888788
        >>
        >> It's the same function, whether it's bound or not....[/color]
        >
        > No, it's not the same function. You got the same id because you didn't
        > bind B.bar and b.bar to anything so the id was reused.
        >[color=green][color=darkred]
        > >>> class B(object):[/color][/color]
        > ... def bar(self): pass
        > ...[color=green][color=darkred]
        > >>> Bbar = B.bar
        > >>> bbar = B().bar
        > >>> Bbar[/color][/color]
        > <unbound method B.bar>[color=green][color=darkred]
        > >>> bbar[/color][/color]
        > <bound method B.bar of <__main__.B object at 0x008759B0>>[color=green][color=darkred]
        > >>> id(Bbar)[/color][/color]
        > 10751312[color=green][color=darkred]
        > >>> id(bbar)[/color][/color]
        > 10736624[color=green][color=darkred]
        > >>> Bbar is bbar[/color][/color]
        > False
        >
        > Kent[/color]

        To elaborate on this, once 'id' is called, you drop the reference.
        This allows quite surprising things like:[color=blue][color=green][color=darkred]
        >>> id(7**8) == id(8**7)[/color][/color][/color]
        True[color=blue][color=green][color=darkred]
        >>> a, b = 7**8, 8**7
        >>> id(a) == id(b) # this time there are other references to a and b[/color][/color][/color]
        False

        If you wanted to test the original code for identity match:[color=blue][color=green][color=darkred]
        >>> B.bar is B().bar[/color][/color][/color]
        False
        is the appropriate test (the 'is' test holds the identities through
        the comparison).

        By the by, this is tricky stuff, nobody should expect to understand
        it thoroughly without both study and testing.

        --Scott David Daniels
        scott.daniels@a cm.org

        Comment

        • Schüle Daniel

          #5
          Re: UnboundMethodTy pe and MethodType

          [...]
          [color=blue][color=green]
          >> It's the same function, whether it's bound or not. Thus, it should
          >> always have the same type.[/color]
          >
          >
          > No, it's not the same function. You got the same id because you didn't
          > bind B.bar and b.bar to anything so the id was reused.[/color]

          thank you for the explanation
          it's indeed tricky with reusing the id
          are there some pages on the net to read more about it?
          [color=blue][color=green][color=darkred]
          >>> class Q:[/color][/color][/color]
          .... def __init__(self,v al):
          .... self.val = val
          .... def bar(self):
          .... print self.val
          ....[color=blue][color=green][color=darkred]
          >>> x = Q.bar
          >>> y = Q("test").bar
          >>> x[/color][/color][/color]
          <unbound method Q.bar>[color=blue][color=green][color=darkred]
          >>> y[/color][/color][/color]
          <bound method Q.bar of <__main__.Q instance at 0x40427a6c>>[color=blue][color=green][color=darkred]
          >>> y()[/color][/color][/color]
          test[color=blue][color=green][color=darkred]
          >>> id(x)[/color][/color][/color]
          1078081812[color=blue][color=green][color=darkred]
          >>> id(y)[/color][/color][/color]
          1078082492[color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          the same id-value would enforce two objects to be
          of the same type (trivial case)
          the reverse is not necessarily true
          in this case x.bar and y.bar are of the same type

          UnboundMethodTy pe is still not very suitable name for Q().bar
          :-/

          Regards, Daniel

          Comment

          • Kirk McDonald

            #6
            Re: UnboundMethodTy pe and MethodType

            Scott David Daniels wrote:[color=blue]
            > To elaborate on this, once 'id' is called, you drop the reference.
            > This allows quite surprising things like:[color=green][color=darkred]
            > >>> id(7**8) == id(8**7)[/color][/color]
            > True[color=green][color=darkred]
            > >>> a, b = 7**8, 8**7
            > >>> id(a) == id(b) # this time there are other references to a and b[/color][/color]
            > False
            >
            > If you wanted to test the original code for identity match:[color=green][color=darkred]
            > >>> B.bar is B().bar[/color][/color]
            > False
            > is the appropriate test (the 'is' test holds the identities through
            > the comparison).
            >
            > By the by, this is tricky stuff, nobody should expect to understand
            > it thoroughly without both study and testing.
            >
            > --Scott David Daniels
            > scott.daniels@a cm.org[/color]

            You know what? That makes perfect sense. Thank you.

            -Kirk McDonald

            Comment

            • Scott David Daniels

              #7
              Re: UnboundMethodTy pe and MethodType

              Kirk McDonald wrote:[color=blue]
              > Scott David Daniels wrote: <an elaboration on ids and refcounts>
              >
              > You know what? That makes perfect sense. Thank you.[/color]

              Thanks a lot for mentioning this. I do try to help out, and sometimes
              it feels like talking to the wind. A thanks every now and then is
              greatly appreciated.

              Just for fun, you can play with:

              import sys
              sys.getrefcount (123**18)
              vs.
              sys.getrefcount (12)

              You should know that 'small' integers are kept and shared once built.
              Similarly, some strings (including all one-character strings and strings
              that might be identifiers).
              sys.getrefcount ('a')
              sys.getrefcount ('probably_not_ really_a_variab le')

              --Scott David Daniels
              scott.daniels@a cm.org

              Comment

              Working...