Python convert function to method

[Example code]-Convert builtin function type to method type (in Python 3)

which is run through Cython and compiled into an extension module. Suppose now I’d like to make this function a method on a class. For example:

class Counter: def __init__(self): self.count = 0 from compiled_extension import increment Counter.increment = increment 

Now this will not work, as the calling convention at the C level will be broken. For example:

>>> c = Counter() >>> c.increment() Traceback (most recent call last): File "", line 1, in TypeError: increment() takes exactly one argument (0 given) 

But in Python 2, we can convert the function to an unbound method by doing:

Counter.increment = types.MethodType(increment, None, Counter) 

How can I accomplish this same thing in Python 3?

One simple way is to use a slim wrapper:

from functools import wraps def method_wraper(f): def wrapper(*args, **kwargs): return f(*args, **kwargs) return wraps(f)(wrapper) Counter.increment = method_wrapper(increment) 

Is there a more efficient way to do it?

Import the extension like this:

import compiled_extension 
def increment: return compiled_extension.increment() 

This seems more readable and might be more efficient.

First thing is getting the names correctly:

>>> def increment(obj): . obj.count += 1 . >>> class A(object): . def __init__(self): . self.count = 0 . >>> o = A() >>> o.__init__ > >>> increment

So proper names are functions and bound methods. Now you can look for how to Bind an Unbound Method and you will probably end up reading about descriptors:

In general, a descriptor is an object attribute with «binding behavior», one whose attribute access has been overridden by methods in the descriptor protocol. Those methods are __get__ , __set__ , and __delete__ . If any of those methods are defined for an object, it is said to be a descriptor.

You can easily transform function to method by just using different invocation of __get__

>>> increment.__get__(None, type(None)) >>> increment.__get__(o, type(o)) > 

And it works like a charm:

>>> o = A() >>> increment.__get__(None, type(None))(o) >>> o.count 1 >>> increment.__get__(o, type(o))() >>> o.count 2 

You can easily add these newly bounded methods to objects:

def increment(obj): obj.count += 1 def addition(obj, number): obj.count += number class A(object): def __init__(self): self.count = 0 o = A() o.inc = increment.__get__(o) o.add = addition.__get__(o) print(o.count) # 0 o.inc() print(o.count) # 1 o.add(5) print(o.count) # 6 

Or create your own descriptor that will will convert function to bound method:

class BoundMethod(object): def __init__(self, function): self.function = function def __get__(self, obj, objtype=None): print('Getting', obj, objtype) return self.function.__get__(obj, objtype) class B(object): def __init__(self): self.count = 0 inc = BoundMethod(increment) add = BoundMethod(addition) o = B() print(o.count) # 0 o.inc() # Getting  print(o.count) # 1 o.add(5) # Getting  print(o.count) # 6 

And you also can see that this is nicely consistent with function/bound method principles:

Class dictionaries store methods as functions. In a class definition, methods are written using def and lambda, the usual tools for creating functions. The only difference from regular functions is that the first argument is reserved for the object instance. By Python convention, the instance reference is called self but may be called this or any other variable name.

To support method calls, functions include the __get__() method for binding methods during attribute access. This means that all functions are non-data descriptors which return bound or unbound methods depending whether they are invoked from an object or a class.

And functions becomes bound method during instance initialization:

>>> B.add # Getting None  >>> o.add # Getting   
  • Convert builtin function type to method type (in Python 3)
  • Override builtin type __str__ method in python
  • Python 3 type hint for a factory method on a base class returning a child class instance
  • how to convert Python 2 unicode() function into correct Python 3.x syntax
  • Python type hints for function returning multiple return values
  • Python 3 type hints for function signature
  • Python Typing: declare return value type based on function argument
  • Is it possible to mock the builtin len() function in Python 3.6?
  • Python type hinting own class in method
  • Type of Python function pointer
  • How to access Type Hints inside of a method after it’s called in Python
  • How to annotate Python function using return type of another function?
  • Python Abstract Method With It’s own __init__ function
  • Are the keys of a kwargs argument to Python function guaranteed to be type string?
  • Python type hinting to return class in function
  • Finding the proper Python type hint, for instance, the signature of the built-in function map()
  • Python 3.6 type hinting for a function accepting generic class type and instance type of the same generic type
  • Potential Exceptions using builtin str() type in Python
  • In Python 3.5, how can I specify a function as a type hint?
  • Python 2 and 3 compatible method to convert bytes to integer
  • Python json.dumps TypeError: Object of type ‘set’ is not JSON serializable , when trying convert from variable , working when hardcoded
  • Writing a function in Python 3 to convert base 16 to base 10
  • Python type annotations: return type of inherited method
  • Is it possible to convert a python function into a class?
  • How to distinguish an instance method, a class method, a static method or a function in Python 3?
  • How to call get or any method of requests library of python by passing a method name to function argument?
  • type hint clone function in python 3.5+
  • How should one do upper level method that returns self with python pep484 type checking
  • Did Python 3.9 update how to type hint the function type?
  • How to annotate the type of a decorator of an async function in Python 3.7?
  • Python function to read video and convert to frames
  • Python annotate return type as the type given to function
  • Python builtin idiom to apply a function to each element of an iterable when we don’t care about the output
  • Best Practice for defining method type in python
  • How to get type annotation within python function scope?
  • Python function decorator should print full method name
  • Python 3 function to convert «Д» to string
  • Is there any type in python that I can’t convert into a string?
  • Proper way hint ‘->’ mutiple return type in python function
  • How to write python polyglot unittest for method using type function?
  • Type the name of an object in python interpreter — what method is it called?
  • Homework, Python 3: Changing a Variable Type From Within a Function
  • Python: How to specify function return type in a mixin method
  • Python 3 exec method : NameError: name of a defined function is not defined
  • Check the owner type in `__set_name__` method introduced in python 3.6+ PEP-0487
  • Python type annotation for a function that accepts a type and returns a value of given type
  • Can I make class method in Python to take argument in type of this class?
  • How to call a builtin function (or method) from C code of a Python extension module?
  • Python 3.8 treats «open» as imported openpyxl method instead of built-in function
  • Python typing for enum type in function argument

More Query from same tag

  • How to find and print the page titles of HTML links from one URL in Python 3.5?
  • Load package but package with same name is already loaded
  • How to skip a for loop by X amount and continue for Y amount, then repeat
  • Automatically decorating every instance method in a class
  • How to test Python objects for non-equality?
  • How can I make pip install package data (a config file)?
  • Print magnified ASCII alphabet patterns side-by-side
  • bsddb3 cannot read whole file
  • Is it advisable to use print statements in a python function rather than return
  • How to remove polar gridlines and add major axis ticks
  • Minidom — check if tag is present in XML
  • Tkinter app using selenium not responding after clicking run
  • How to remove some pairs from list?
  • Coin Counter in Raspberry Pi (RPi-GPIO)
  • Implementing a Canvas in PyQt5
  • More pythonic/better way to write this?
  • What’s wrong with inputting a list inside a function?
  • Socket not getting connected Python
  • Why is this python code using eval function not producing an error?
  • Printing prime numbers in range
  • How to change a Python 3 module to a package without changing the imports?
  • How do I add a reaction to the message I just sent
  • Issue parsing a xhtml page using Python
  • Memory consumption of a list and set in Python
  • How execute python command within virtualenv with Visual Studio Code
  • Python3.4 — Install pyautogui — Raspberry Pi 3
  • How to setup a cloud run app to receive pub/sub messages in python?
  • How can I schedule multiple tasks using asyncio constructs in a loop
  • Joining .wav files without writing on disk in Python
  • Matching Input Text in HTML parse with Python
  • Python, print string on the same line for screen output
  • HTML string in python file doesn’t execute as expected
  • Some websites dont fully load/render in selenium headless mode
  • How to detect the end of a line in Python
  • Money and TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given

Источник

From Function to Method

Python newcomers often have hard time understanding the «magic» behind Python’s methods. And the truth is that Python’s object model can be a bit peculiar when compared to most mainstream (or not-so-mainstream) object-oriented programming languages. (There are quite a few threads on c.l.py with either direct or indirect questions about what makes a Python method.)

Here’s a brief — but hopefully helpful — overview of what exactly is a Python method, showing how Python magically inserts self or cls into the argument list of a method call.

From Function .

The def statement always yields a function object. Always. If you don’t believe it, try the following snippet:

class Foo(object): def bar(self): return «baaz» print type(Foo.bar) # print type(Foo.__dict__[‘bar’]) #

So, why is it that type(Foo.bar) is not the same as type(Foo.__dict__['bar'])? The answer is: attribute lookup rules and the descriptor protocol.

. To Method, via the Descriptor Protocol

The return value of this call becomes the result of the attribute lookup. This mechanism is what provides support for computed attributes.

The function type implements this descriptor protocol. So when a function is an attribute of a class object and you access it as an attribute of the class itself, its __get__ method is called with None and the class as arguments. When you access it as an attribute of an instance of the class, its __get__ method is called with the instance and the class as arguments.

With the instance object (if any) and class object available, it’s easy to create a method object that wraps the function object. This is itself a callable object; calling it mostly injects the instance as the first item in the argument list and returns the result of calling the wrapped function object.

A (naive) implementation of the whole thing might look like this:

class method(object): def __init__(self, func, instance, cls): self.im_func = func self.im_self = instance self.im_class = cls def __call__(self, *args, **kw): # XXX : all sanity checks removed for readability if self.im_self: args = (self.im_self,) + args return self.im_func(*args, **kw) class function(object): def __get__(self, instance, cls): return method(self, instance, cls)

So, what turns a function into a method is not that the function is defined in a class statement’s body (well, not directly at least). Rather, it’s that the function is an attribute of the class. For what it’s worth, the following code is perfectly legal:

class Foo(object): pass def func(obj): print "obj is %s " % obj Foo.method = func f = Foo() f.method() # all three of these Foo.method(f) # invocations produce func(f) # the same result

References

FromFunctionToMethod (last edited 2014-07-23 10:01:07 by mjpieters )

Источник

Читайте также:  Java rest assured xml
Оцените статью