Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #60283 > unrolled thread
| Started by | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| First post | 2013-11-23 09:28 +0100 |
| Last post | 2013-11-24 17:08 +0100 |
| Articles | 16 — 6 participants |
Back to article view | Back to comp.lang.python
Behavior of staticmethod in Python 3 Marco Buttu <marco.buttu@gmail.com> - 2013-11-23 09:28 +0100
Re: Behavior of staticmethod in Python 3 Peter Otten <__peter__@web.de> - 2013-11-23 10:01 +0100
Re: Behavior of staticmethod in Python 3 Marco Buttu <marco.buttu@gmail.com> - 2013-11-23 10:39 +0100
Re: Behavior of staticmethod in Python 3 Peter Otten <__peter__@web.de> - 2013-11-23 16:23 +0100
Re: Behavior of staticmethod in Python 3 Marco Buttu <marco.buttu@gmail.com> - 2013-11-23 10:39 +0100
Re: Behavior of staticmethod in Python 3 Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-23 13:48 +0000
Re: Behavior of staticmethod in Python 3 Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-11-23 16:00 +0100
Re: Behavior of staticmethod in Python 3 Chris Angelico <rosuav@gmail.com> - 2013-11-24 08:38 +1100
Re: Behavior of staticmethod in Python 3 Peter Otten <__peter__@web.de> - 2013-11-23 22:51 +0100
Re: Behavior of staticmethod in Python 3 Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-11-24 11:30 +0100
Re: Behavior of staticmethod in Python 3 Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-24 14:18 +0000
Re: Behavior of staticmethod in Python 3 Peter Otten <__peter__@web.de> - 2013-11-24 11:43 +0100
Re: Behavior of staticmethod in Python 3 Ian Kelly <ian.g.kelly@gmail.com> - 2013-11-24 03:45 -0700
Re: Behavior of staticmethod in Python 3 Peter Otten <__peter__@web.de> - 2013-11-24 12:03 +0100
Re: Behavior of staticmethod in Python 3 Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-11-24 16:55 +0100
Re: Behavior of staticmethod in Python 3 Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-11-24 17:08 +0100
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2013-11-23 09:28 +0100 |
| Subject | Behavior of staticmethod in Python 3 |
| Message-ID | <l6povp$ndp$1@speranza.aioe.org> |
In Python 3 the following two classes should be equivalent:
$ cat foo.py
class Foo:
def foo():
pass
print(callable(foo))
class Foo:
@staticmethod
def foo():
pass
print(callable(foo))
But they do not:
$ python3 foo.py
True
False
How come the metaclass does not skip the staticmethod decorator?
--
Marco Buttu
[toc] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-11-23 10:01 +0100 |
| Message-ID | <mailman.3076.1385197282.18130.python-list@python.org> |
| In reply to | #60283 |
Marco Buttu wrote: > In Python 3 the following two classes should be equivalent: Says who? > $ cat foo.py > class Foo: > def foo(): > pass > print(callable(foo)) > > class Foo: > @staticmethod > def foo(): > pass > print(callable(foo)) > > But they do not: > > $ python3 foo.py > True > False > > How come the metaclass does not skip the staticmethod decorator? What? Your print()s are executed inside the class body, so the classes don't come into play at all. Your script is saying that a staticmethod instance is not a callable object. It need not be because Foo.foo() doesn't call the Foo.foo attribute directly, it calls Foo.foo.__get__(None, Foo)() >>> class D: ... def __get__(self, *args): print(args) ... >>> class Foo: ... foo = D() ... >>> Foo.foo() (None, <class '__main__.Foo'>) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'NoneType' object is not callable Look for "descriptor protocol" to learn the details.
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2013-11-23 10:39 +0100 |
| Message-ID | <529077E0.8090603@gmail.com> |
| In reply to | #60285 |
On 11/23/2013 10:01 AM, Peter Otten wrote:
>> In Python 3 the following two classes should be equivalent:
> Says who?
>
>> >$ cat foo.py
>> >class Foo:
>> > def foo():
>> > pass
>> > print(callable(foo))
>> >
>> >class Foo:
>> > @staticmethod
>> > def foo():
>> > pass
>> > print(callable(foo))
>> >
>> >But they do not:
>> >
>> >$ python3 foo.py
>> >True
>> >False
>>
>
> Your script is saying that a staticmethod instance is not a callable object.
> It need not be because
>
> Foo.foo()
Yes, you are right about Python 3. But in Python 2, if I am not going
wrong, there is not solution, and I need to define a function outside
the class. For instance:
$ cat config.py
class Configuration(object):
def positiveCheck(value):
if not value > 0:
raise AttributeError('Must be a positive number')
attributes = {
# Attribute name: (type, checkrule)
'myattr': (int, positiveCheck),
}
def __setattr__(self, name, value):
if not name in Configuration.attributes:
raise AttributeError("Attribute `%s` non allowed." %name)
expected_type, checkrule = Configuration.attributes[name]
if not isinstance(value, expected_type):
raise TypeError('The value %s is not of type %s' \
%(value, expected_type.__name__))
if callable(checkrule):
print('calling %s(%s)' %(checkrule.__name__, value))
checkrule(value)
super(Configuration, self).__setattr__(name, value)
The positive check works fine:
>>> from config import Configuration
>>> c = Configuration()
>>> c.myattr = -10
calling positiveCheck(-10)
Traceback (most recent call last):
...
AttributeError: Must be a positive number
But I cannot use the method as a function:
>>> Configuration.positiveCheck(-10)
Traceback (most recent call last):
...
Configuration instance as first argument (got int instance instead).
Furthemore, I cannot use the method as a staticmethod, becase otherwise
it will not be callable inside the class body.
--
Marco Buttu
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-11-23 16:23 +0100 |
| Message-ID | <mailman.3089.1385220205.18130.python-list@python.org> |
| In reply to | #60287 |
Marco Buttu wrote:
> On 11/23/2013 10:01 AM, Peter Otten wrote:
>
>>> In Python 3 the following two classes should be equivalent:
>> Says who?
>>
>>> >$ cat foo.py
>>> >class Foo:
>>> > def foo():
>>> > pass
>>> > print(callable(foo))
>>> >
>>> >class Foo:
>>> > @staticmethod
>>> > def foo():
>>> > pass
>>> > print(callable(foo))
>>> >
>>> >But they do not:
>>> >
>>> >$ python3 foo.py
>>> >True
>>> >False
>>>
>>
>> Your script is saying that a staticmethod instance is not a callable
>> object. It need not be because
>>
>> Foo.foo()
>
> Yes, you are right about Python 3. But in Python 2, if I am not going
> wrong, there is not solution, and I need to define a function outside
> the class. For instance:
>
> $ cat config.py
> class Configuration(object):
>
> def positiveCheck(value):
> if not value > 0:
> raise AttributeError('Must be a positive number')
>
> attributes = {
> # Attribute name: (type, checkrule)
> 'myattr': (int, positiveCheck),
> }
Just add
positiveCheck = staticmethod(positiveCheck)
at this point and everything should work in both Python 2 and 3.
Alternatively use Steven's callable_staticmethod as a decorator.
>
> def __setattr__(self, name, value):
> if not name in Configuration.attributes:
> raise AttributeError("Attribute `%s` non allowed." %name)
>
> expected_type, checkrule = Configuration.attributes[name]
> if not isinstance(value, expected_type):
> raise TypeError('The value %s is not of type %s' \
> %(value, expected_type.__name__))
> if callable(checkrule):
> print('calling %s(%s)' %(checkrule.__name__, value))
> checkrule(value)
>
> super(Configuration, self).__setattr__(name, value)
>
> The positive check works fine:
>
> >>> from config import Configuration
> >>> c = Configuration()
> >>> c.myattr = -10
> calling positiveCheck(-10)
> Traceback (most recent call last):
> ...
> AttributeError: Must be a positive number
>
> But I cannot use the method as a function:
>
> >>> Configuration.positiveCheck(-10)
> Traceback (most recent call last):
> ...
> Configuration instance as first argument (got int instance instead).
>
> Furthemore, I cannot use the method as a staticmethod, becase otherwise
> it will not be callable inside the class body.
PS: AttributeErrors should be raised when an attribute does not exist or
cannot be set; I recommend that you raise a ValueError in positiveCheck().
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2013-11-23 10:39 +0100 |
| Message-ID | <mailman.3078.1385199596.18130.python-list@python.org> |
| In reply to | #60285 |
On 11/23/2013 10:01 AM, Peter Otten wrote:
>> In Python 3 the following two classes should be equivalent:
> Says who?
>
>> >$ cat foo.py
>> >class Foo:
>> > def foo():
>> > pass
>> > print(callable(foo))
>> >
>> >class Foo:
>> > @staticmethod
>> > def foo():
>> > pass
>> > print(callable(foo))
>> >
>> >But they do not:
>> >
>> >$ python3 foo.py
>> >True
>> >False
>>
>
> Your script is saying that a staticmethod instance is not a callable object.
> It need not be because
>
> Foo.foo()
Yes, you are right about Python 3. But in Python 2, if I am not going
wrong, there is not solution, and I need to define a function outside
the class. For instance:
$ cat config.py
class Configuration(object):
def positiveCheck(value):
if not value > 0:
raise AttributeError('Must be a positive number')
attributes = {
# Attribute name: (type, checkrule)
'myattr': (int, positiveCheck),
}
def __setattr__(self, name, value):
if not name in Configuration.attributes:
raise AttributeError("Attribute `%s` non allowed." %name)
expected_type, checkrule = Configuration.attributes[name]
if not isinstance(value, expected_type):
raise TypeError('The value %s is not of type %s' \
%(value, expected_type.__name__))
if callable(checkrule):
print('calling %s(%s)' %(checkrule.__name__, value))
checkrule(value)
super(Configuration, self).__setattr__(name, value)
The positive check works fine:
>>> from config import Configuration
>>> c = Configuration()
>>> c.myattr = -10
calling positiveCheck(-10)
Traceback (most recent call last):
...
AttributeError: Must be a positive number
But I cannot use the method as a function:
>>> Configuration.positiveCheck(-10)
Traceback (most recent call last):
...
Configuration instance as first argument (got int instance instead).
Furthemore, I cannot use the method as a staticmethod, becase otherwise
it will not be callable inside the class body.
--
Marco Buttu
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-11-23 13:48 +0000 |
| Message-ID | <5290b244$0$29993$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #60283 |
On Sat, 23 Nov 2013 09:28:43 +0100, Marco Buttu wrote:
> In Python 3 the following two classes should be equivalent:
They certainly are not equivalent in *any* version of Python, because
staticmethods are not equivalent to instance methods.
> $ cat foo.py
> class Foo:
> def foo():
> pass
> print(callable(foo))
>
> class Foo:
> @staticmethod
> def foo():
> pass
> print(callable(foo))
>
> But they do not:
>
> $ python3 foo.py
> True
> False
And Python 2 gives the same result for staticmethods:
[steve@ando ~]$ python2.7
Python 2.7.2 (default, May 18 2012, 18:25:10)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
py>
py> class Test(object):
... @staticmethod
... def method():
... pass
... print callable(method)
...
False
> How come the metaclass does not skip the staticmethod decorator?
What makes you think the metaclass gets the opportunity to skip the
decorator? By the time the metaclass gets called, the decorator has
already run.
You seem to be conflating behaviour in Python 2 that doesn't actually
occur. Staticmethods are not directly callable in any version of Python.
The problem you seem to have is that you want to call a method both
during and after construction:
class MyClass(object):
def helper(arg):
return arg + 1
x = helper(10)
y = helper(20)
def method(self, arg):
return self.helper(arg)
Here, the attributes x and y rely on calling helper as a function, where
it does not receive a self argument, but when calling helper from inside
the instance method, or when calling it like MyClass.helper(), it will
receive a self argument.
Unfortunately there is no good solution to this using just built-ins.
staticmethod doesn't work, as it's not callable. However, we can create
our own callable version of staticmethod:
class callable_staticmethod(object):
def __init__(self, func):
self.func = func
def __get__(self, obj, cls=None):
return self.func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
class MyClass(object):
@callable_staticmethod
def helper(arg):
return arg + 1
x = helper(10)
y = helper(20)
def method(self, arg):
return self.helper(arg)
This should now work exactly as you hope.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-11-23 16:00 +0100 |
| Message-ID | <mailman.3099.1385242084.18130.python-list@python.org> |
| In reply to | #60283 |
Op 23-11-13 10:01, Peter Otten schreef: > > Your script is saying that a staticmethod instance is not a callable object. > It need not be because > > Foo.foo() > > doesn't call the Foo.foo attribute directly, it calls > > Foo.foo.__get__(None, Foo)() I think you are burdening the programmer with implemantation details that don't matter to him. IMO if Foo.foo() is legal then Foo.foo is callable. That the actual call is delegated to Foo.foo.__get__(None, Foo) shouldn't matter. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-11-24 08:38 +1100 |
| Message-ID | <mailman.3100.1385242739.18130.python-list@python.org> |
| In reply to | #60283 |
On Sun, Nov 24, 2013 at 2:00 AM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> IMO if Foo.foo() is legal then Foo.foo is callable. That the actual call
> is delegated to Foo.foo.__get__(None, Foo) shouldn't matter.
I absolutely agree. But isn't that already the case? I seem to be
missing something here.
>>> class Foo:
@staticmethod
def foo():
pass
>>> callable(Foo.foo)
True
>>> callable(Foo().foo)
True
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-11-23 22:51 +0100 |
| Message-ID | <mailman.3101.1385243464.18130.python-list@python.org> |
| In reply to | #60283 |
Antoon Pardon wrote: > Op 23-11-13 10:01, Peter Otten schreef: > >> >> Your script is saying that a staticmethod instance is not a callable >> object. It need not be because >> >> Foo.foo() >> >> doesn't call the Foo.foo attribute directly, it calls >> >> Foo.foo.__get__(None, Foo)() > > I think you are burdening the programmer with implemantation details > that don't matter to him. > > IMO if Foo.foo() is legal then Foo.foo is callable. That the actual call > is delegated to Foo.foo.__get__(None, Foo) shouldn't matter. If you read the original post -- I think in this case the details do matter. What is your highlevel explanation for >> class Foo: ... @staticmethod ... def foo(): pass ... try: foo() ... except Exception as err: ... print(err) ... 'staticmethod' object is not callable >>> Foo.foo() or maybe clearer: >>> @staticmethod ... def foo(): pass ... >>> def bar(): pass ... >>> class Foo: ... foo = foo ... bar = bar ... >>> Foo.bar is bar True >>> Foo.foo is foo False How would you explain that without mentioning the descriptor protocol?
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-11-24 11:30 +0100 |
| Message-ID | <mailman.3121.1385289032.18130.python-list@python.org> |
| In reply to | #60283 |
Op 23-11-13 22:51, Peter Otten schreef: > Antoon Pardon wrote: > >> Op 23-11-13 10:01, Peter Otten schreef: >> >>> >>> Your script is saying that a staticmethod instance is not a callable >>> object. It need not be because >>> >>> Foo.foo() >>> >>> doesn't call the Foo.foo attribute directly, it calls >>> >>> Foo.foo.__get__(None, Foo)() >> >> I think you are burdening the programmer with implemantation details >> that don't matter to him. >> >> IMO if Foo.foo() is legal then Foo.foo is callable. That the actual call >> is delegated to Foo.foo.__get__(None, Foo) shouldn't matter. > > If you read the original post -- I think in this case the details do matter. > > What is your highlevel explanation for I don't care about what kind of explanation. I care about a correct answer to the question whether a particular object is callable (from a programmers point of view). I'm sure you can give a very comprehensive explanation for why in this case we get an incorrect answer but that doesn't make the behaviour correct. Foo.foo() is legal here. So Foo.foo is callable. So you starting with it needn't be callable is using "callable" with a different meaning than the natural interpretation. Al the rest is just an attempt in getting others to accept your use of "callable" instead of the natural one. Foo.foo() being legal and Foo.foo not being callable is IMO a bug in python. No matter what explanation you have for the behaviour. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-11-24 14:18 +0000 |
| Message-ID | <52920a9f$0$29993$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #60357 |
On Sun, 24 Nov 2013 11:30:14 +0100, Antoon Pardon wrote:
> Foo.foo() is legal here. So Foo.foo is callable.
Incorrect. Foo.foo() is legal for *any* identifiers Foo and foo. Since
Python is an extremely dynamic language, the compiler cannot (easily, or
at all) prohibit "illegal" combinations. The only combinations which are
illegal are those which are not legal identifier, e.g.:
while.spam
abc$xyz.eggs
Otherwise, any pair of legal identifiers are legal and will be accepted
by the compiler. Only at runtime does the lookup succeed or fail:
str.length # likely to fail, unless str has been shadowed
str.find # likely to succeed, unless str has been shadowed
If the lookup has succeeded, then and only then does a second lookup
occur, namely:
type(str.find).__call__
and if that succeeds it is called.
It isn't helpful to talk about function or method calls being "legal" or
"illegal" in Python, since such things are normally determined in terms
of *success* or *failure*, not permitted versus prohibited. Either the
full chain of lookups and function call will succeed, or something will
raise an exception and it will fail.
> Foo.foo() being legal and Foo.foo not being callable is IMO a bug in
> python. No matter what explanation you have for the behaviour.
I don't know why you keep going on about this point, since this is NOT
the behaviour the original poster is talking about. With foo decorated as
a staticmethod in class Foo, Foo.foo *is* callable. It takes 30 seconds
to try it yourself:
py> class Foo(object): # inherit from object necessary in Python 2
... @staticmethod
... def foo():
... return "Success!"
...
py>
py> Foo.foo()
'Success!'
py> Foo().foo()
'Success!'
This is not what the OP is talking about. Try this instead:
py> Foo.__dict__['foo']()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
What's going on here? Let's have a look:
py> Foo.__dict__['foo']
<staticmethod object at 0x9d83194>
py> Foo.foo
<function foo at 0x9d80294>
You CANNOT understand this behaviour without understanding the descriptor
protocol, which is *fundamental* to Python, and has been since Python
2.2. Regular instance methods, class methods, static methods and
properties are all defined in terms of descriptors. Trying to understand
them without knowledge of descriptors is like trying to understand
generators and iterators without knowledge of StopIteration -- you can go
only so far before you get stuck and confused.
The OP discovered that you can call a regular function inside a class
body, outside of a method, during the class statement:
class MyClass:
def function():
return "stuff"
attr = function()
This works, but then you can't call MyClass().function() as it will
raise. So the OP tried making it a staticmethod:
class MyClass:
@staticmethod
def function():
return "stuff"
attr = function()
but that fails, because *staticmethod instances are not callable*. They
are descriptors. Only after the descriptor protocol gets a chance to run
do you get a callable function.
*This is not a bug.* Making staticmethod instances callable is a feature
enhancement, not a bug fix. Or you could just define your own callable-
staticmethod descriptor, it's easy enough to do.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-11-24 11:43 +0100 |
| Message-ID | <mailman.3122.1385289800.18130.python-list@python.org> |
| In reply to | #60283 |
Antoon Pardon wrote: > Foo.foo() being legal and Foo.foo not being callable is IMO a bug in > python. Foo.foo() is legal, and Foo.foo is callable.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-11-24 03:45 -0700 |
| Message-ID | <mailman.3123.1385289947.18130.python-list@python.org> |
| In reply to | #60283 |
On Sun, Nov 24, 2013 at 3:30 AM, Antoon Pardon <antoon.pardon@rece.vub.ac.be> wrote: > Op 23-11-13 22:51, Peter Otten schreef: >> Antoon Pardon wrote: >> >>> Op 23-11-13 10:01, Peter Otten schreef: >>> >>>> >>>> Your script is saying that a staticmethod instance is not a callable >>>> object. It need not be because >>>> >>>> Foo.foo() >>>> >>>> doesn't call the Foo.foo attribute directly, it calls >>>> >>>> Foo.foo.__get__(None, Foo)() >>> >>> I think you are burdening the programmer with implemantation details >>> that don't matter to him. >>> >>> IMO if Foo.foo() is legal then Foo.foo is callable. That the actual call >>> is delegated to Foo.foo.__get__(None, Foo) shouldn't matter. >> >> If you read the original post -- I think in this case the details do matter. >> >> What is your highlevel explanation for > > I don't care about what kind of explanation. I care about a correct answer to > the question whether a particular object is callable (from a programmers point > of view). I'm sure you can give a very comprehensive explanation for why in > this case we get an incorrect answer but that doesn't make the behaviour correct. > > Foo.foo() is legal here. So Foo.foo is callable. So you starting with it needn't > be callable is using "callable" with a different meaning than the natural > interpretation. Al the rest is just an attempt in getting others to accept your > use of "callable" instead of the natural one. > > Foo.foo() being legal and Foo.foo not being callable is IMO a bug in python. No matter > what explanation you have for the behaviour. Your supposition that Foo.foo is not considered callable by Python is false, as Chris already demonstrated, and I don't see where anybody here has stated otherwise. What Peter wrote was that "a staticmethod instance is not a callable object", which is absolutely correct, and these two facts are consistent because Foo.foo is not a staticmethod instance (Foo.__dict__['foo'] on the other hand *is* a staticmethod instance and *is not* callable, and Foo.__dict__['foo']() will correspondingly raise a TypeError).
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-11-24 12:03 +0100 |
| Message-ID | <mailman.3124.1385290954.18130.python-list@python.org> |
| In reply to | #60283 |
Antoon Pardon wrote: > Op 23-11-13 10:01, Peter Otten schreef: > >> >> Your script is saying that a staticmethod instance is not a callable >> object. It need not be because >> >> Foo.foo() >> >> doesn't call the Foo.foo attribute directly, it calls >> >> Foo.foo.__get__(None, Foo)() > > I think you are burdening the programmer with implemantation details > that don't matter to him. Replacing "you" in your statement with "python" I was about to suggest to make staticmethod(func) callable when I found this had already been rejected: [Python-Dev] Making staticmethod objects callable? Nicolas Fleury nidoizo at yahoo.com Wed Mar 1 15:57:12 CET 2006 https://mail.python.org/pipermail/python-dev/2006-March/061948.html If you think you have compelling arguments, go ahead and explain them -- preferably on python-ideas.
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-11-24 16:55 +0100 |
| Message-ID | <mailman.3141.1385308585.18130.python-list@python.org> |
| In reply to | #60283 |
Op 24-11-13 11:43, Peter Otten schreef: > Antoon Pardon wrote: > >> Foo.foo() being legal and Foo.foo not being callable is IMO a bug in >> python. > > Foo.foo() is legal, and Foo.foo is callable. Indeed, I had a kink in my brain which made it difficult to see where I was going wrong myself. Sorry about that. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-11-24 17:08 +0100 |
| Message-ID | <mailman.3142.1385309418.18130.python-list@python.org> |
| In reply to | #60283 |
Op 24-11-13 12:03, Peter Otten schreef: > Antoon Pardon wrote: > >> Op 23-11-13 10:01, Peter Otten schreef: >> >>> >>> Your script is saying that a staticmethod instance is not a callable >>> object. It need not be because >>> >>> Foo.foo() >>> >>> doesn't call the Foo.foo attribute directly, it calls >>> >>> Foo.foo.__get__(None, Foo)() >> >> I think you are burdening the programmer with implemantation details >> that don't matter to him. > > Replacing "you" in your statement with "python" I was about to suggest to > make staticmethod(func) callable when I found this had already been > rejected: > > [Python-Dev] Making staticmethod objects callable? > Nicolas Fleury nidoizo at yahoo.com > Wed Mar 1 15:57:12 CET 2006 > > https://mail.python.org/pipermail/python-dev/2006-March/061948.html > > If you think you have compelling arguments, go ahead and explain them -- > preferably on python-ideas. I am under no illusion that compelling arguments will make any difference. People had argued for a ternary operator for years and it all fell on deaf ears until finally a python developer was bitten by a nasty bug while using one of the alternative that was always suggested here. When you asked that python should behave following the principle of least surprise and thus showed consistency where possible, the standard trope was that a foolish consistency was the hobgoblin of little minds. I see no reason why this should go any way differently now. -- Antoon Pardon
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web