473,405 Members | 2,338 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,405 software developers and data experts.

Using function parameters to determine method kind

I was wondering if anyone has suggested having Python determine
a method's kind from its first parameter. 'self' is a de facto
reserved word; 'cls' is a good indicator of a class method
( __new__ is a special case ). The closest to this I could find
was the 2002-12-04 posting 'metaclasses and static methods'
by Michele Simionato. The posting's example metaclass uses the
method's name. I present my own example of automatic method
kind declaration. Being a module with some support functions
and a test case it is too large to post so is available online at:

http://www3.telus.net/len_l/Python_Explorations.html

as dparams.py .

# dparams.py example
from dparams import Object
class C(Object):
def __init__(self, x): # instance method
self.x = x
def MyClass(cls): # class method
print cls
def MyStatic(a): # static method
print a
def MyStatic2(self):
print self
MyStatic2 = staticmethod(MyStatic2) # still works
Lenard Lindstrom
<le***@telus.net>
Jul 18 '05 #1
9 2732
Lenard Lindstrom <le***@telus.net> wrote in message news:<4q**********@telus.net>...
I was wondering if anyone has suggested having Python determine
a method's kind from its first parameter. 'self' is a de facto
reserved word; 'cls' is a good indicator of a class method
( __new__ is a special case ).


I find relaying on tbe parameter name to specify the kind of method
to be rather fragile. It works most times but not always. What about
inner classes for instance? Also, there are situations where you want
a method to work both with instances and classes, so do you want to
use self or cls?
I support PEP 318 also because this will kill home grown hacks (including
my own) to provide this kind of functionality.
I am also waiting for a better "super" but it seems nobody is talking
about it.

Michele Simionato
Jul 18 '05 #2
On 5 Apr 2004 05:17:39 -0700, mi***************@poste.it (Michele
Simionato) wrote:

[text snipped]
I am also waiting for a better "super" but it seems nobody is talking
about it.


Well then, here is your chance: what are the problems of super? I also
found that it has a couple of glitches, but I'd like to know more.

With my best regards,
G. Rodrigues
Jul 18 '05 #3
Michele Simionato <mi***************@poste.it> wrote:
Lenard Lindstrom <le***@telus.net> wrote in message
news:<4q**********@telus.net>...
I was wondering if anyone has suggested having Python determine
a method's kind from its first parameter. ....
I find relaying on tbe parameter name to specify the kind of method
to be rather fragile. It works most times but not always. What about
inner classes for instance? Do you mean:
from dparams import Object
class A(Object):
class B(Object):
def __init__(self, x): self.x = x
b=A.B(x)
?
Class A.B is not affected. Parameter checking only happens for
instances of type function. Other callables have to be or
use descriptors to be anything other than static. As for B's
methods, parameter checking works just fine. My module is
more of a demonstration than a practical solution anyway.
I would suggest a different approach for implementing
parameter checking in the python interpreter.
Also, there are situations where you want
a method to work both with instances and classes, so do you want to
use self or cls? I can only imagine one way to do this now, wrap the function in a
descriptor.
from dparams import Object
from types import MethodType
class bimethod(Object): .... def __init__(self, f): self.f=f
.... def __get__(self, o, t):
.... if o is None: return MethodType(self.f, t, type(t))
.... return MethodType(self.f, o, t)
.... class A(Object): .... def bi(x): return x
.... bi=bimethod(bi)
.... A.bi() <class '__main__.A'> A().bi()

<__main__.A object at 0x0119C1B0>

Descriptors are unaffected by the function's parameters, so the first
parameter can be anything you want. If I am not mistaken, the only
methods other that __new__ that currently work without descriptors
are instance methods. Is it not good form for instance methods to
start with 'self' anyways? (except maybe for a metaclass's __init__,
but this is a special case)
I support PEP 318 also because this will kill home grown hacks (including
my own) to provide this kind of functionality. This is a good PEP. It would complement the use of parameters.
I am also waiting for a better "super" but it seems nobody is talking
about it.

I gave it a try by changing the type argument passed to a descriptor's
__get__ method, but it required a rewritten classmethod of course.

Lenard Lindstrom
<le***@telus.net>
Jul 18 '05 #4
Lenard Lindstrom <le***@telus.net> wrote in message news:<8y**********@telus.net>...
Michele Simionato <mi***************@poste.it> wrote:
Lenard Lindstrom <le***@telus.net> wrote in message
news:<4q**********@telus.net>...
I was wondering if anyone has suggested having Python determine
a method's kind from its first parameter. ...
I find relaying on tbe parameter name to specify the kind of method
to be rather fragile. It works most times but not always. What about
inner classes for instance? Do you mean:
from dparams import Object
class A(Object):
class B(Object):
def __init__(self, x): self.x = x
b=A.B(x)
?


No, I had in mind this (contrived) example:

class Outer(object):
def outermeth(self1):
class Inner(object):
def innermeth(self2):
<do-something-with-self1-and-self2>
...

It is nice to have the ability to give any name to "self".
Class A.B is not affected. Parameter checking only happens for
instances of type function. Other callables have to be or
use descriptors to be anything other than static. As for B's
methods, parameter checking works just fine. My module is
more of a demonstration than a practical solution anyway.
I would suggest a different approach for implementing
parameter checking in the python interpreter.
Also, there are situations where you want
a method to work both with instances and classes, so do you want to
use self or cls? I can only imagine one way to do this now, wrap the function in a
descriptor.
from dparams import Object
from types import MethodType
class bimethod(Object): ... def __init__(self, f): self.f=f
... def __get__(self, o, t):
... if o is None: return MethodType(self.f, t, type(t))
... return MethodType(self.f, o, t)
... class A(Object): ... def bi(x): return x
... bi=bimethod(bi)
... A.bi() <class '__main__.A'> A().bi()

<__main__.A object at 0x0119C1B0>

Descriptors are unaffected by the function's parameters, so the first
parameter can be anything you want. If I am not mistaken, the only
methods other that __new__ that currently work without descriptors
are instance methods.


?? All methods works with descriptors, what do you mean?
Is it not good form for instance methods to
start with 'self' anyways? (except maybe for a metaclass's __init__,
but this is a special case)


It is not a special case (no special case is special enough or something
like that).
Jul 18 '05 #5
Gonçalo Rodrigues <op*****@mail.telepac.pt> wrote in message news:<kn********************************@4ax.com>. ..
On 5 Apr 2004 05:17:39 -0700, mi***************@poste.it (Michele
Simionato) wrote:

[text snipped]
I am also waiting for a better "super" but it seems nobody is talking
about it.


Well then, here is your chance: what are the problems of super? I also
found that it has a couple of glitches, but I'd like to know more.

With my best regards,
G. Rodrigues


I wrote once an essay collecting all the shortcomings of "super" I found in my
explorations; maybe one day or another I will finish it and post it somewhere.
But it requires a good amount of work, so do not expect it too soon.

Michele Simionato
Jul 18 '05 #6
mi***************@poste.it (Michele Simionato) writes:
Lenard Lindstrom <le***@telus.net> wrote in message
news:<8y**********@telus.net>...
Michele Simionato <mi***************@poste.it> wrote:
Lenard Lindstrom <le***@telus.net> wrote in message
news:<4q**********@telus.net>...
> I was wondering if anyone has suggested having Python determine
> a method's kind from its first parameter. ...
I find relaying on tbe parameter name to specify the kind of method
to be rather fragile. It works most times but not always. What about
inner classes for instance?
.... No, I had in mind this (contrived) example:

class Outer(object):
def outermeth(self1):
class Inner(object):
def innermeth(self2):
<do-something-with-self1-and-self2>
...

It is nice to have the ability to give any name to "self". Yes, I see what you mean. The best I can suggest is:

class Outer(object):
def outermethod(self1):
class Inner(object):
def innermeth(self2):
...
innermeth = instancemethod(innermeth)
outermeth = instancemethod(outermethod)

or
def outermethod(self):
self1 = self
... def innermethod(self):
self2 = self

I believe there is a use for a builtin instancemethod descriptor anyways.
It can wrap callables not of type python function.

.... Descriptors are unaffected by the function's parameters, so the first
parameter can be anything you want. If I am not mistaken, the only
methods other that __new__ that currently work without descriptors
are instance methods.


?? All methods works with descriptors, what do you mean?

By descriptor I mean wrapper classes like staticmethod. A naked function
can only be an instance method descriptor, which by convention has
a first parameter of 'self'. __new__ is exceptional in that it is an
instance method that is always called as an unbound method. I see though
that __new__ would break if accidentally made a class method.
Is it not good form for instance methods to
start with 'self' anyways? (except maybe for a metaclass's __init__,
but this is a special case)


It is not a special case (no special case is special enough or something
like that).

I thought a metaclass's __init__ was a special case because it was called
from the meta meta-class, usually by method type.__call__. So maybe it
could be called as an unbound method to avoid problems if it was not
an instance method. But isn't type.__call__ the factory function for
all new-style objects, not just classes? I also overlooked cooperative
__init__ calls for multiple metaclass inheritance. So yes, there is nothing
special about a metaclass's __init__ other than it is usually declared
with 'cls' rather than 'self' as a first parameter. This is enough to
convince me that a method's first argument is not a reliable
indicator of method kind.

All this talk about python functions just being another kind
of descriptor makes me wonder if it is not time to revive
the idea of having type function subclassable:

class C(object):
def f(c):
__factory__ = classfunction # No confusion here
...

issubclass(classfunction, type(lambda: None)) # True
isinstance(C.f.im_func, classfunction) # True

:-)

Thanks for answering my questions.

Lenard Lindstrom
<le***@telus.net>
Jul 18 '05 #7
Lenard Lindstrom <le***@telus.net> wrote in message news:<u0**********@telus.net>...
By descriptor I mean wrapper classes like staticmethod. A naked function
can only be an instance method descriptor, which by convention has
a first parameter of 'self'. __new__ is exceptional in that it is an
instance method that is always called as an unbound method. I see though
that __new__ would break if accidentally made a class method.
Descriptors are a protocol. If an object has a __get__ method it is a
descriptor. Python functions, methods, staticmethods, classmethods,
etc.
are all descriptors. A naked function is a descriptor, even if a
different descriptor from a bound/unbound method or a
staticmethod/classmethod; it can be converted in a staticmethod or a
classmethod or other user-defined
of descriptors. __new__ is a function which is automatically converted
to
a staticmethod and in this sense it is a special case (whereas
__init__ is
not). I think you already know all that, it was just to fix the
terminology.
But isn't type.__call__ the factory function for
all new-style objects, not just classes?

type.__call__ is tricky since "type" is its own metaclass.
What do you have in mind exactly? Classes (as opposed to poor
man instances that cannot be instantiated) are made by type.__new__
which is called by type(type).__call__ which is type.__call__.

This snippet should explain the dynamics of meta-metaclasses (which
I think you understand already, but your explanation is a bit
confusing):

class MM(type):
def __call__(mcl,name,bases,dic):
print "calling MM.__call__"
return super(MM,mcl).__call__(name,bases,dic)
class M(type):
__metaclass__=MM
def __new__(mcl,name,bases,dic):
print "calling M.__new__"
return super(M,mcl).__new__(mcl,name,bases,dic)
class C(object):
"""This class is created by the metaclass M, so M.__new__ is
called,
but not directly. First type(M).__call__ is called, i.e.
MM.__call__"""
__metaclass__=M

The output is:

calling MM.__call__
calling M.__new__
All this talk about python functions just being another kind
of descriptor makes me wonder if it is not time to revive
the idea of having type function subclassable:


You may want to look at this thread:

http://groups.google.it/groups?hl=it....lang.python.*
Jul 18 '05 #8
In reply Michele Simionato's <mi***************@poste.it> posting:
<95*************************@posting.google.com>

I apologize that my replies are becoming more difficult to understand.
It is just that I have had to rethink a few things regarding my
initial proposal. So I will just start fresh here.

When I first posted my question on using a function's first parameter
to determine method kind I had a very specific idea on how to
implement it in Python. Type function becomes subtypable and several
builtin subtypes are made available. The root type has no __get__
descriptor method so is a static method by nature. It has two subtypes
having __get__ methods: an instancefunction is what we now call FunctionType,
and a classfunction. A function's first parameter determines which type
is created at function declaration:

def fs(x): pass # I am a static function
def fi(self): pass # I am an instance function
def fc(cls): pass # I am a class function

If the first parameter is neither 'self' or 'cls' the function
is static by default.

Of course no such scheme is worth proposing if it breaks too much
existing code. Therefore the posting to comp.lang.python. I can
imagine serious breakage only if instance methods are customarily
declared without a first argument 'self'. Instance methods are the
only case where a function's __get__ method matters. In every other
case the function is wrapped in some descriptor class instance
and the function is called directly as an unbound method.
Unfortunately there is an exception to the 'self' naming convension:
the __init__ and __new__ methods of a metaclass. I hoped they were somehow
handled differently from the usual __init__ and __new__ calls of object
instance creation, but they are not. So the 'self' coding convension
has exceptions. I am now convinced my original idea is impractical.

My example module 'dparams.py' uses a metaclass to wrap functions in
staticmethod or classmethod descriptors at class creation,
but I consider this a less than ideal solution. And to implement
it in Python means that 'object' can no longer be of type 'type'.
I believe this is unacceptable. So I consider the issue of using
parameters to determine method kind closed.
All this talk about python functions just being another kind
of descriptor makes me wonder if it is not time to revive
the idea of having type function subclassable:


You may want to look at this thread:

http://groups.google.it/groups?hl=it....lang.python.*


I was actually being somewhat serious. It is just the syntax of:

def foo(x):
__factory__ = staticfunction

that is questionable.

def(staticfunction) foo(x):
...

may be more appropriate.

As for that thread you mentioned in you posting on subtyping
FunctionType, here it is:

http://groups.google.com/groups?hl=e...org%26rnum%3D1

I actually did make FunctionType subtypable in a prerelease
version of python 2.3 and it did not crash or act strange.
At the time I made the above posting I was playing with function
currying and tried to extend FunctionType by adding some curry
operators. It didn't work:

"TypeError: type 'function' is not an acceptable base type"

But as the thread continued my ideas on function currying changed
and it seemed less important to subtype function, so my postings stop
making a lot of sense; it became more important to me to have
a consistent way of doing introspection on callables. I made
FunctionType subtypable just to prove a point. I was a
stranger to the Python community and the Unix diff and patch
tools so I did not try to submit a patch. The interpreter has
since dissappeared into my trashbin as newer releases of Python
can out. But if there is enough interest and I have the time I
may try and do it again.

Lenard Lindstrom
<le***@telus.net>
Jul 18 '05 #9

From: "Michele Simionato" <mi***************@poste.it>
No, I had in mind this (contrived) example:

class Outer(object):
def outermeth(self1):
class Inner(object):
def innermeth(self2):
<do-something-with-self1-and-self2>
...

It is nice to have the ability to give any name to "self".
like that).


Strange, I would have thought that self1 would not be in scope (it's not in
the local scope and it's not in the global scope AFAICT). If true, you'd
have to have a parameter to your innermeth, which you can call whatever you
want so call it self1. Have scoping rules changed in Python?

Oliver
Jul 18 '05 #10

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

Similar topics

0
by: Nashat Wanly | last post by:
HOW TO: Call a Parameterized Stored Procedure by Using ADO.NET and Visual C# .NET View products that this article applies to. This article was previously published under Q310070 For a Microsoft...
11
by: Grasshopper | last post by:
Hi, I am automating Access reports to PDF using PDF Writer 6.0. I've created a DTS package to run the reports and schedule a job to run this DTS package. If I PC Anywhere into the server on...
0
by: Lokkju | last post by:
I am pretty much lost here - I am trying to create a managed c++ wrapper for this dll, so that I can use it from c#/vb.net, however, it does not conform to any standard style of coding I have seen....
7
by: Mark Waser | last post by:
Hi all, I'm trying to post multipart/form-data to a web page but seem to have run into a wall. I'm familiar with RFC 1867 and have done this before (with AOLServer and Tcl) but just can't seem...
10
by: ndm | last post by:
Hi, Just wondering if any one knows a way to pass and enumerate an unknown number of parameter to a VB function. I want to create a Min/Max functions that can: a) take an variable number of...
21
by: abcd | last post by:
In my code I am debating whether or not to validate the types of data being passed to my functions. For example def sayHello(self, name): if not name: rasie "name can't be null" if not...
6
by: cppnow | last post by:
Hello. I have a strange conceptual problem I'm trying to think about. I would like to build a library that allows the user to do the following: 1) User defined types: The user defines their...
6
by: tshad | last post by:
I was looking at a page that showed how to set up a custom event and it seems to work ok. But I am not sure how I would use it. How would I subscribe to it. There is actual action (such as...
0
by: J. Cliff Dyer | last post by:
On Thu, 2008-11-13 at 11:19 -0600, Chris Mellon wrote: He is using an object. Specifically, he's using a function object. Though perhaps you meant put it into a class. Here are a few essays...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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
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.