0

Why output is:

<class 'method'>                                                                                                                    
<class 'method'>                                                                                                                        
<class 'function'>                                                                                                                      
<class 'function'>

not

<class 'method'>                                                                                                                         
<class 'method'>
<class 'method'>                                                                                                                                <class 'method'>

Code

class A:

    def ftest(self, a, *args):
        b = args[0]
        self.r = a+b

f_ref = ftest

f_dict = {
    'ftest': ftest,
    'f_ref': f_ref
}

inst = A()

print(type(inst.ftest))
print(type(inst.f_ref))

print(type(inst.f_dict['ftest']))
print(type(inst.f_dict['f_ref']))

I've made a funtion routing cmd args and type 'function' instead 'method' causes exceptions (I'm not passing self, I don't know whether variable is function or function pointing to method).

JoshuaCS
  • 2,524
  • 1
  • 13
  • 16
patrykbajos
  • 384
  • 3
  • 17
  • 1
    Because a method is an object that binds a function to an instance, but the functions in the class are just functions unless they are accessed via the instance, where they become bound methods – juanpa.arrivillaga Jan 11 '19 at 21:32
  • So Is there a way to check if function (which is a method) expects `self` as argument? – patrykbajos Jan 11 '19 at 21:33
  • Is there only one instance? How would you know otherwise? Just use `my_instance.my_method` and pass *that*, it will have the instance bound, which is what you need. – juanpa.arrivillaga Jan 11 '19 at 21:36
  • 3
    @bajos: `self` is purely by convention, and unbound methods are plain functions, indistinguishable from any other function not defined within a class. – ShadowRanger Jan 11 '19 at 21:36

1 Answers1

0

The first two are bound methods and the last two are unbound methods. In the end, all are functions, the only difference is that bound methods receives the associated instance object as first parameter (self):

class A:

  def __init__(self, p):
    self.p = p

  def print_p(self):
    print(self.p)

a = A(10)

a.print_p() # This is equivalent
A.print_p(a) # to this

Refer to this for more info

JoshuaCS
  • 2,524
  • 1
  • 13
  • 16
  • 2
    In Python 3, there are no unbound methods. Just functions, but yes. – juanpa.arrivillaga Jan 11 '19 at 21:36
  • 1
    Adding to @juanpa.arrivillaga: This is why the OP's goal isn't really possible; unless accessed via a class instance, the "methods" are just plain functions, same as a function defined outside of a class, so you can't tell the difference between a "maybe method" and a "pure function". – ShadowRanger Jan 11 '19 at 21:38
  • @juanpa.arrivillaga Well, I just said **unbound methods** to diferentiate them from _standard_ functions, but you are right. – JoshuaCS Jan 11 '19 at 21:38
  • 1
    @JosuéCortina well *exactly*, there *is no distinction in Python 3*. – juanpa.arrivillaga Jan 11 '19 at 21:39