473,414 Members | 1,615 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

Method behavior for user-created class instances

Greetings.

I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.

Eg.

class foo:
def __call__(self, inst): pass

class bar:
meth = foo()

such that bar().meth() will not raise an exception for too few
arguments (because the inst argument in foo.__call__ is implicitly set
to the bar instance). I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions. The need for this arises out of
the implementation of a function decorator as a class.

Thanks.
Jul 14 '08 #1
4 1042
cr***********@gmail.com wrote:
Greetings.

I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.

Eg.

class foo:
def __call__(self, inst): pass

class bar:
meth = foo()

such that bar().meth() will not raise an exception for too few
arguments (because the inst argument in foo.__call__ is implicitly set
to the bar instance). I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions. The need for this arises out of
the implementation of a function decorator as a class.

Thanks.
While it is not clear "why" you would want this, I believe this works.
If not, take a look at staticmethods or classmethods, they might work for you.
>>class foo(object):
.... def __call__(self, inst):
.... print "foo.__call__", inst
....
>>class bar:
.... def __init__(self):
.... self.foo = foo()
.... self.meth = self.foo.__call__
....
>>b = bar()
b.meth(1)
foo.__call__ 1

-Larry
Jul 15 '08 #2
On Jul 14, 9:04 pm, Larry Bates <larry.ba...@websafe.com`wrote:
crazychimp...@gmail.com wrote:
Greetings.
I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.
Eg.
class foo:
def __call__(self, inst): pass
class bar:
meth = foo()
such that bar().meth() will not raise an exception for too few
arguments (because the inst argument in foo.__call__ is implicitly set
to the bar instance). I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions. The need for this arises out of
the implementation of a function decorator as a class.
Thanks.

While it is not clear "why" you would want this, I believe this works.
If not, take a look at staticmethods or classmethods, they might work for you.
>>class foo(object):
... def __call__(self, inst):
... print "foo.__call__", inst
...
>>class bar:
... def __init__(self):
... self.foo = foo()
... self.meth = self.foo.__call__
...
>>b = bar()
>>b.meth(1)
foo.__call__ 1

-Larry
This doesn't work for me. I have a class which is used to decorate
functions, returning a callable object in the place of the original
function. So, instances of this class must be able to be used anywhere
a function would be used, and this means getting method behavior when
it is used in a class body.

A working implementation would be (in 3.0):

from functools import partial
from abc import ABCMeta, abstractmethod

class method_behavior(metaclass = ABCMeta):
def __get__(self, instance, owner):
if instance is None:
return self.__call__
return partial(self.__call__, instance)

@abstractmethod
def __call__(): pass

Then, any decorator class can inherit from it:

class foo(method_behavior):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwds):
print("calling decorated func")
return self.func(*args, **kwds)

Then, we can decorate a function with foo (via @foo) and it will work
either inside a class body or outside, it works everywhere an
undecorated function would work, eg.:

@foo
def bar():
print('bar')

class baz:
@foo
def bar(self):
print('bar')

What I am asking is whether there is a way to directly inherit method
behavior, instead of inexactly rewriting it as I did in
method_behavior.__get__().
Jul 15 '08 #3
On 15 juil, 01:24, crazychimp...@gmail.com wrote:
Greetings.

I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.
You need to implement the descriptor protocol the same way the
function type do.

import types

class Foo(object):
def __call__(self, instance):
print "%s - %s" % (self, instance)

def __get__(self, instance, cls):
return types.MethodType(self, instance, cls)

class Bar(object):
foo = Foo()

b = Bar()
b.foo()

I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions.
Extending types.FunctionType doesn't work OOTB (there's some
incompatibility wrt/ metaclasses)
Jul 15 '08 #4
On Jul 15, 9:53 am, "bruno.desthuilli...@gmail.com"
<bruno.desthuilli...@gmail.comwrote:
On 15 juil, 01:24, crazychimp...@gmail.com wrote:
Greetings.
I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.

You need to implement the descriptor protocol the same way the
function type do.

import types

class Foo(object):
def __call__(self, instance):
print "%s - %s" % (self, instance)

def __get__(self, instance, cls):
return types.MethodType(self, instance, cls)

class Bar(object):
foo = Foo()

b = Bar()
b.foo()
I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions.

Extending types.FunctionType doesn't work OOTB (there's some
incompatibility wrt/ metaclasses)
Thanks, this got me started in writing it for 3.0. There are no more
unbound methods in 3.0, so a check for whether instance is None is
necessary to give the right behavior. Here is the final implementation
I came up with:

from abc import ABCMeta, abstractmethod
from functools import update_wrapper
from types import MethodType

class decorator(metaclass = ABCMeta):
def __init__(self, function):
update_wrapper(self, function)
self.function = function

def __get__(self, instance, cls):
if instance is None:
return self
return MethodType(self, instance)

@abstractmethod
def __call__(): pass

To use it, write a class that inherits decorator and overrides
__call__, probably doing something with self.function.
Jul 15 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: OKB (not okblacke) | last post by:
I've noticed some peculiar behavior from copy.deepcopy: if you pass it a method or function object, it raises a TypeError somewhere in copy_reg saying "function() takes at least 2 arguments (0...
2
by: Asp Help | last post by:
I'm working on a ASP applicatition to create Windows 2000 users. Because I don't want everybody to have access to the site I've changed te security in IIS 5.0 which runs on a windows 2000 Sp4...
10
by: Andres Eduardo Hernando | last post by:
Hi, I'm not entirely sure this is the right group to ask this question, but I saw a similar one above, and the group's charter is not clear enough about it, so, here I go: ;) What is the...
1
by: Jonathan Yong | last post by:
I observe a very weird behavior when dynamically create web control and bind events to it. Create a C# ASP.NET application, Put a PlaceHolder and Textbox onto the Web form, and try with the 4...
5
by: moondaddy | last post by:
I have a website where cataloge pages are populated by calling a stored procedure on sql server. I use the sql data adapter's fill method to call this stored procedure and fill the dataset. about...
94
by: smnoff | last post by:
I have searched the internet for malloc and dynamic malloc; however, I still don't know or readily see what is general way to allocate memory to char * variable that I want to assign the substring...
2
by: smichr | last post by:
It seems to me that the indices() method for slices is could be improved. Right now it gives back concrete indices for a range of length n. That is, it does not return any None values. Using an...
122
by: C.L. | last post by:
I was looking for a function or method that would return the index to the first matching element in a list. Coming from a C++ STL background, I thought it might be called "find". My first stop was...
6
by: John | last post by:
I have a multi-user Access database with back- and front end on the network. Problem is that the forms don't get refreshed automatically: if user A enters a record it will only become available to...
9
by: josh logan | last post by:
Hello, I need a round function that _always_ rounds to the higher integer if the argument is equidistant between two integers. In Python 3.0, this is not the advertised behavior of the built-in...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.