Difference between 'function' and 'method'

castironpi at gmail.com castironpi at gmail.com
Fri Mar 7 02:46:43 CET 2008


On Mar 6, 7:10 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
> En Thu, 06 Mar 2008 22:56:33 -0200, <castiro... at gmail.com> escribió:
>
> > On Mar 6, 5:35 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
>
> >> p = P()
> >> print p.bar.func_name # -> bar
> >> p.bar.im_func.anotherattribute = 1
> >> print p.bar.anotherattribute # -> 1
>
> >> (the attribute must be set on the *function* itself if you want it to  
> >> be  
> >> somewhat persistent; methods are usually volatile objects)
>
> > You read my mind.
>
> You could try to write in a way that reading your mind isn't necesary...
>
> > I was just getting:
> >    assert p.bar is p.bar
> > and failing.
>
> > But if you set them on im_func, instances don't have their own.
>
> Instances don't have their own methods either. What do you actually want  
> to do? If you need a method with per-instance attributes, that looks like  
> another object to me.

Hi, great thanks for giving me your ear this far.

First of all, -I have it working-.  But the design isn't encapsulated
quite right.  Here's what I have.  69 lines, so I'll ask to post it
first.  The gist is:

class ISS( SS, metaclass= autonaming ):
	message= MessageDec()
	@message
	def user_act( msg, self, change ):
		print( 'user act self change',
			msg, self, change )

IncomingServer... but it originally came from 'clientsideserver.'

iss= ISS()

class OSS( SS, metaclass= autonaming ):
	message= MessageDec()
	user_act= message.out()

oss= OSS()

oss.message is a abstraction class that writes the method name into a
string, then sends it to OSS... outgoingserver or serverside.

Now that I'm writing it, and this is important, -to- the -newsgroup-,
I realize you could do it with a simple wrapper... include the
function name in parameters and call the pickler and send.

OSS then looks like this:

def something_happens( *ar ):
    self.user_act( something_about( *ar ) )

So the message.out() instance pickles ( 'user_act', ar ) and sends
it.  Then iss.incoming receives it, unpickles that string, gets
'user_act' from self, and invokes.

The cool part is the declaration of user_act= message.out(), which
uses a metaclass to assign its own name, and returns a function which
includes the object in its signature.  Cool.

Yes it's working and a little slack.  However-: this is the cool
part.  I'd like messages to know which instance they came from, and
perform the sending & receiving encapsulated on their own--- not to
subclass class SS( Sending ): with various behaviors: that is, to
assign them as class attributes rather than superclasses.

The dreaming comes in here--- I'd like the class to look just like
this.  Tell me it's possible.

And I changed my mind on posting the code, here's the whole thing.
Just get SS.send and SS.incoming into MessageDec.  har har har har
har.  Change anything before class OSS:.  How does a weak reference
lookup in doublebound sound?



from functools import wraps
import pickle

class doublebound:
	__slots__ = ( '_func', 'assname', '_orig' )
	def __init__( self, func ):
		@wraps( func )
		def f( *ar, **kws ):
			return func( self, *ar, **kws )
		self.assname= None
		self._func, self._orig= f, func
	def __get__( self, instance, owner ):
		return self._func.__get__( instance, owner )

class autonaming( type ):
	def __init__( self, name, bases, namespace ):
		for k,v in namespace.items():
			if isinstance( v, doublebound ):
				v.assname= k

class Sending:
	def send( *ar, **kws ): raise NotImplemented

class MessageDec:
	def __call__( self, fun ):
		return doublebound( fun )
	def out( self ):
		return doublebound( self._send )
	def _send( self, message, other, *ar, **kws ):
		return other.send(
			message.assname, *ar, **kws )

class SS( Sending ):
	def send( self, methn, *ar, **kws ):
		transpmessage= methn, ar, kws
		transpstr= pickle.dumps( transpmessage )
		self.far.incoming( transpstr )
	def incoming( self, transpstr ):
		transpmessage= pickle.loads( transpstr )
		methn, ar, kws= transpmessage
		meth= getattr( self, methn )
		meth( *ar, **kws )

class OSS( SS, metaclass= autonaming ):
	message= MessageDec()
	user_act= message.out()
	somethingelse= message.out()
	@message
	def amessage( msg, self, *change ):
		print( 'something else', change )

class ISS( SS, metaclass= autonaming ):
	message= MessageDec()
	@message
	def user_act( msg, self, change ):
		print( 'user act self change',
			msg, self, change )
	@message
	def somethingelse( msg, self, change= 'and' ):
		print( 'something else', change )
	amessage= message.out()

oss= OSS()
iss= ISS()
oss.far= iss
iss.far= oss
oss.user_act(2)
oss.somethingelse( 'butwhat?')
iss.amessage( 2, 3, 4, 5 )



More information about the Python-list mailing list