Re: The right way to 'call' a class attribute inside the same class

2016-12-19 Thread Thomas 'PointedEars' Lahn
Chris Angelico wrote:

> On Mon, Dec 19, 2016 at 9:52 AM, Erik  wrote:
>> 1) Method call:
>>"obj.foo(1, 2, 3)" is syntactic sugar for "obj.foo(obj, 1, 2, 3)".
> 
> And the bit you have to be REALLY careful of when working with both
> Python and JS is that you have to have "obj.foo(...)" as a single
> expression. Consider:
> 
> # Python
> lst = []
> func = lst.append
> func(1); func(2); func(3)
> # lst now holds [1,2,3]
> 
> // JavaScript
> var arr = []
> var func = arr.push.bind(arr) // IMPORTANT
> func(1); func(2); func(3)
> // arr now contains [1,2,3]
> 
> If you just take "arr.push", you don't get a bound method. You get an
> unbound method. You have to explicitly bind that back to the array
> object, or its "this" pointer won't be set.

“this” is not a pointer, it is a built-in variable (adj.) *value*.  There 
are no (high-level) pointers in implementations of ECMAScript (there may be 
in the language used to *build* the *implementation*, e.g. C++).  Instead, 
there are reference values referring to objects.

With func(…), “this” would be set to a reference to the global object in 
non-strict mode, and to “undefined” in strict mode.

But the question here is: Why would one insist to declare a (global) 
variable, and assign to it a reference to the Array.prototype.push() method 
instead of calling the “push” method directly, accessed through the 
prototype chain?  *This* certainly is _not_ how you should do this in 
ECMAScript implementations, but instead:

  /* arr now contains [1,2,3] */
  arr.push(1, 2, 3);

Because “this” is *always* set to a reference to the calling (or 
constructed) object, if any (if there is no explicit object, it depends on 
the execution mode; see above).

At best, yours is a bad example following a misconception.
 
> This is so important (eg with callback functions) that JS introduced a
> new type of function to help deal with the problem...

Or because "JS" is “the world’s most misunderstood programming language” 
(Crockford, and I agree with him on *that*), as ISTM you just demonstrated.

There is no “new type of function”.  Using Function.prototype.bind() this 
way (it is not available in implementations of ECMAScript Ed. 4 and earlier) 
is functionally equivalent to

  func.call(arr, …, …);

aso.  It is syntactic sugar so that you can write

  var func2 = func.bind(this);
  func2(…);

and do not have to write, e.g.,

  var that = this;
  var func2 = function () {
func.call(that, …, …);
  };
  func2(…);

but it is not necessarily more efficient than a simple call of 
Function.prototype.call() or Function.prototype.apply().

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-18 Thread Chris Angelico
On Mon, Dec 19, 2016 at 9:52 AM, Erik  wrote:
>
> 1) Method call:
>"obj.foo(1, 2, 3)" is syntactic sugar for "obj.foo(obj, 1, 2, 3)".

And the bit you have to be REALLY careful of when working with both
Python and JS is that you have to have "obj.foo(...)" as a single
expression. Consider:

# Python
lst = []
func = lst.append
func(1); func(2); func(3)
# lst now holds [1,2,3]

// JavaScript
var arr = []
var func = arr.push.bind(arr) // IMPORTANT
func(1); func(2); func(3)
// arr now contains [1,2,3]

If you just take "arr.push", you don't get a bound method. You get an
unbound method. You have to explicitly bind that back to the array
object, or its "this" pointer won't be set.

This is so important (eg with callback functions) that JS introduced a
new type of function to help deal with the problem...

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-18 Thread Erik


NOTE: If you found this message by searching for help on how Python 
works, be aware that it's discussing how JavaScript works, not Python! 
Look elsewhere :)


Chris, this isn't directed at you (I think you get it) - just following 
up with some detail for anyone who might discover this sub-thread when 
searching in future.


On 18/12/16 01:21, Chris Angelico wrote:

On Sun, Dec 18, 2016 at 12:01 PM, Erik  wrote:

I wish I could find the resource I originally learned this stuff from,
because it's quite enlightening and I'd like to link to it here



Sounds like how Michael Schwern introduces his "Git for Ages 4 and Up"
talk


Just in case anyone is remotely interested, I've found a reasonable link 
(but it's not the one I was looking for).


I realise this is off-topic for a Python list, but it has come up 
because of a Python question so I thought why not ... (I wish someone 
had explained this to me in roughly-Python terms when I first had to 
deal with JS ;)).


In short, AIUI, all JS functions have an implicit initial parameter 
which is named 'this'. What that parameter is bound to depends on the 
context of the call to that function object. In Python the callable is 
of a particular type (method, function, generator) but on JS (for the 
purposes of this discussion (pun intended ;)) they are all equal and 
it's the calling context that determines what happens.


A JS function, whether declared with "function Foo(a, b, c) {}" or as an 
expression "function (a, b, c) {}" has an implicit initial parameter 
which is bound to the variable 'this' (so they are really "function 
Foo(this, a, b, c) {}", "function (this, a, b, c) {}").


The value of that initial first parameter is determined by how they are 
called. There are three main ways:


1) Method call:
   "obj.foo(1, 2, 3)" is syntactic sugar for "obj.foo(obj, 1, 2, 3)".

2) Function call:
   "foo(1, 2, 3)" is syntactic sugar for "foo(GLOBAL_OBJECT, 1, 2, 3)" 
where "GLOBAL_OBJECT" is whatever the execution environment defines as 
being the global object. In a browser, I think it's "window", in the JS 
strict mode, I think it's "undefined" (i.e., no object), in Node.js I 
think it might be something else entirely.


3) Constructor call:
   "new foo(1, 2, 3)" is syntactic sugar for "foo(NEWOBJ, 1, 2, 3)" 
where NEWOBJ is a newly allocated, empty object.


The other way of invoking a function object is via its "call" method 
where the initial 'this' parameter can be explicitly given - 
"foo.call(SPAM, 1, 2, 3)" - which is how to implement bound methods and 
that sort of thing.



The main area of confusion seems to be when passing function expressions 
(closures) as a callback to another function:


function Foo() {
  ham(this.a, this.b, function (x) { this.frobnicate(x); });
}

Let's assume this is called with "obj.Foo();". In the function itself, 
'this', is bound to 'obj'. However, in the body of the (anonymous) 
function expression/closure (which sort of looks to be at the same scope 
as everything else) 'this' is bound according to the rules above being 
applied to at the point it is called - the object it is bound to almost 
certainly doesn't have the "frobnicate" method expected.


This is why the following works:

function Foo() {
  _this = this;
  ham(this.a, this.b, function (x) { _this.frobnicate(x); });
}

The closure now knows how to address the 'this' object for the original 
method even though it is called later by whatever 'ham()' does. Using a 
bound function as the callback works in the same way.




Anyway, off-topic as I said, but if it helps other Pythoneers get to 
grips with some of the weird JS semantics, it's all good :)




The link I *did* find (which probably has a bit more depth) is:

https://rainsoft.io/gentle-explanation-of-this-in-javascript/


Cheers, E.
--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-17 Thread Chris Angelico
On Sun, Dec 18, 2016 at 12:01 PM, Erik  wrote:
> Yes, in that case there is (I didn't grok that you meant using 'new' by
> "calling a function as a constructor", but it's obvious now you spell it
> out).

Yeah. I thought that I got that terminology from MDN, but I can't find
it now, so it must have been from elsewhere.

> I wish I could find the resource I originally learned this stuff from,
> because it's quite enlightening and I'd like to link to it here - if one
> understands how things work generally under the covers it all makes much
> more sense, but I guess that's also a bad advert for a language (and why a
> lot of people get confused at first, and why it's a bit of a mess ;)).

Sounds like how Michael Schwern introduces his "Git for Ages 4 and Up"
talk - git may have a pretty poor UI, but has such beautiful innards
that it's best to understand it in that way. And he agrees that this
isn't how you _normally_ want to do things. When I explain Python, I
don't start by explaining the byte code interpreter or the operand
stack :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-17 Thread Erik

On 16/12/16 01:17, Chris Angelico wrote:

On Fri, Dec 16, 2016 at 11:36 AM, Erik  wrote:

On 12/12/16 23:23, Chris Angelico wrote:


In JavaScript, it's normal to talk about "calling a function as a
constructor". When you do, there is a 'this' object before you start.



No there isn't. There is an implicit binding of a variable called "this"
based on the syntactic sugar of whether you're calling a function as method
on an object or not.

In "strict" mode, [blah, blah, blah]



I'm talking about when you call a function as a constructor: "new
Foo()". Doesn't that have a 'this' object before the function starts?


Yes, in that case there is (I didn't grok that you meant using 'new' by 
"calling a function as a constructor", but it's obvious now you spell it 
out).


I wish I could find the resource I originally learned this stuff from, 
because it's quite enlightening and I'd like to link to it here - if one 
understands how things work generally under the covers it all makes much 
more sense, but I guess that's also a bad advert for a language (and why 
a lot of people get confused at first, and why it's a bit of a mess ;)).


But yes you're correct, in the case of using "new Func()" then "Func" is 
called with an implicit binding of 'this' that is to a newly created object.


Regards,
E.


--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-15 Thread Chris Angelico
On Fri, Dec 16, 2016 at 11:36 AM, Erik  wrote:
> On 12/12/16 23:23, Chris Angelico wrote:
>>
>> In JavaScript, it's normal to talk about "calling a function as a
>> constructor". When you do, there is a 'this' object before you start.
>
>
> No there isn't. There is an implicit binding of a variable called "this"
> based on the syntactic sugar of whether you're calling a function as method
> on an object or not.
>
> In "strict" mode, this has been redefined to be "undefined" (i.e., there is
> no object) for when you're not - otherwise it will be a binding to the
> global "document" object (and in Node.js, I think something else entirely.
> It's a mess ...).

I'm talking about when you call a function as a constructor: "new
Foo()". Doesn't that have a 'this' object before the function starts?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-15 Thread Erik

On 12/12/16 23:23, Chris Angelico wrote:

In JavaScript, it's normal to talk about "calling a function as a
constructor". When you do, there is a 'this' object before you start.


No there isn't. There is an implicit binding of a variable called "this" 
based on the syntactic sugar of whether you're calling a function as 
method on an object or not.


In "strict" mode, this has been redefined to be "undefined" (i.e., there 
is no object) for when you're not - otherwise it will be a binding to 
the global "document" object (and in Node.js, I think something else 
entirely. It's a mess ...).



Ultimately, every language has slightly different semantics


You're not wrong ;)

E.

--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-15 Thread Erik

On 13/12/16 06:14, Gregory Ewing wrote:

Ned Batchelder wrote:

if a C++ constructor raises an exception, will the corresponding
destructor
be run, or not? (No, because it never finished making an object of
type T.)


So it just leaks any memory that's been allocated by
the partially-run constructor?


If you're referring to resources in general that a constructor (in the 
C++ sense) allocates - memory, file descriptors, whatever - then it's up 
to the constructor to release those resources before throwing the 
exception should something fail. Destructors are not executed for 
objects that were not constructed.


If the constructor is not written to that standard, then yes - it will 
leak resources.


The memory allocated for the _object_ itself will be released though.

Regards, E.
--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Gregory Ewing

Ned Batchelder wrote:

if a C++ constructor raises an exception, will the corresponding destructor
be run, or not? (No, because it never finished making an object of type T.)


So it just leaks any memory that's been allocated by
the partially-run constructor?

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Chris Angelico
On Tue, Dec 13, 2016 at 4:45 PM, Steven D'Aprano
 wrote:
> I don't understand the point of bringing up Javascript. Ben has already said
> that we shouldn't feel the need to mindlessly copy C++ terminology. Is it your
> position that we *should* copy Javascript terminology? Why Javascript and not
> C++ or ObjectiveC? Even when it goes against the obvious English mnemonic?

I'm saying that ALL these terminology debates are needlessly pedantic.
Whatever word you use, you're going to have to explain the Python
semantics as distinct from everyone else's, so don't sweat it. Whether
we call __init__ the constructor or initializer, there is going to be
someone out there who misinterprets it. Go with whatever, pick the
easiest to explain (which is probably "__new__ is allocator, __init__
is initializer"), and don't try to burden the terms alone with the job
of explaining Python's semantics.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Steven D'Aprano
On Tuesday 13 December 2016 10:23, Chris Angelico wrote:

> On Tue, Dec 13, 2016 at 10:17 AM, Ben Finney 
> wrote:
>> If the differences didn't matter I would agree that “overly pedantic” is
>> fair. But those differences trip up newcomers. Thinking of
>> ‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
>> from – am I not meant to be constructing it? — and to attempt to return
>> that instance. And when the time comes to lean about ‘__new__’ the
>> confusion continues, because the newcomer has been told that something
>> *else* is the constructor, so what's this?
> 
> In JavaScript, it's normal to talk about "calling a function as a
> constructor". When you do, there is a 'this' object before you start.
> Should we tell the JavaScript folks to be more pedantic, because
> 'this' should end up existing? 

You've ignored Ben's critical point that if we call __init__ the "constructor", 
what do we call __new__? (Perhaps we should call __new__ the "initialiser" for 
maximum confusion.)

I don't understand the point of bringing up Javascript. Ben has already said 
that we shouldn't feel the need to mindlessly copy C++ terminology. Is it your 
position that we *should* copy Javascript terminology? Why Javascript and not 
C++ or ObjectiveC? Even when it goes against the obvious English mnemonic?

__init__ is the INITialiser (it initialises an existing instance);

__new__ creates/constructs a NEW instance


> Does it really even matter when memory
> gets allocated and the object's identity assigned? 

Actually, yes it does. Try constructing an immutable object like a subclass of 
float, str or int from the __init__ method. Attaching attributes to the 
instance doesn't count.


class PositiveInt(int):
def __init__(self, arg):
arg = abs(arg)
return super().__init__(self, arg)


So much fail...



> Before __init__
> gets called, the object isn't "truly there" - its fundamental
> invariants may not yet have been established, and key attributes might
> not have been set up.

"Fundamental invariants" is tricky though -- are they *truly* fundamental? This 
is Python -- I can easily make a Python-based class that lacks the attributes 
that its methods assume will be there, or delete them after creation.

But there is one thing which truly is fundamental: the instance creation, the 
moment that object.__new__ returns a new instance. Before calling that, the 
instance genuinely doesn't exist; after object.__new__ returns, it genuinely 
does. (Even if it isn't fully initialised.)

Unlike __init__, object.__new__ is atomic: it either succeeds, or it doesn't. 
So object.__new__ really is the constructor of instances, and so following 
standard practice, MyClass.__new__ which inherits from object ought to be 
called the same thing. (Even if it is no longer atomic, due to being written in 
Python.)


> Once __init__ finishes, there is an expectation
> that attributes and invariants are sorted out.
> 
> This is like the old "Python doesn't have variables" thing.
> Ultimately, every language has slightly different semantics (otherwise
> they'd be trivial transformations, like Ook and Brainf*), so you have
> to learn that the "constructor" might have slightly different
> semantics. Accept it - embrace it. Learn it.

We're not debating what other languages should call __new__ and __init__ or 
whatever their equivalents are. We're debating what Python should call them.

For some prior art, consider ObjectiveC. To create a new instance of a class, 
you call:

[[MyClass alloc] init]

where alloc is the "allocator" (it basically just allocates memory, and very 
little else) and init is the "initialiser" (because it initialises the newly 
created instance.

In more modern versions of ObjectiveC, there's a short-cut:

[MyClass new]

where new calls alloc then init for you.

In Ruby, people think of two distinct things as the "constructor", depending on 
what you are doing. [Source: my resident Ruby expert at work.] If you are 
talking about *writing* a class, the constructor is the initialize method:

class MyClass
def initialize
...
end
end

But if you are talking about *creating an instance* it is the new method:

MyClass.new

which itself automatically calls initialize behind the scenes. (I'm told that 
it is possible to override new, but nobody does it.)


It seems to me that both of these are quite similar to Python's model.



-- 
Steven
"Ever since I learned about confirmation bias, I've been seeing 
it everywhere." - Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Steven D'Aprano
On Tuesday 13 December 2016 12:12, Ned Batchelder wrote:

> On Monday, December 12, 2016 at 6:17:43 PM UTC-5, Ben Finney wrote:
>> Ned Batchelder  writes:
>> 
>> > Claiming that __init__ isn't a constructor seems overly pedantic to
>> > me.
>> 
>> Whereas to me, claiming that ‘Foo.__init__’ is a constructor seems
>> needlessly confusing.
>> 
> ...
>> * A constructor should return the instance. ‘Foo.__init__’ does not do
>>   that; ‘Foo.__new__’ does.
> 
> This seems like an odd thing to insist on. C++ and Java constructors
> don't return the instance.

I'm not sure what you mean by that. I think they do, at least in C++.

Normally in C++ you would create an instance like this:

MyClass obj(arg);


In Python terms, that would be written as: `obj = MyClass(arg)`.


But one can also create "anonymous objects" which aren't assigned to a named 
variable:

something.method( MyClass(args) );


Doesn't that count as "returning an instance"?


> C++ allocators return the instance.

As I understand it, C++ allocators are specialist methods used in the standard 
library for container classes which allocate storage, i.e. the equivalent of 
Python lists and dicts.

http://en.cppreference.com/w/cpp/concept/Allocator

As far as I can tell, they aren't relevant to "simple" record- or struct-like 
objects.


> I'm happy to call __new__ an allocator. It serves exactly the same
> role in Python as allocators do in C++: its job is to create the raw
> material for the object, and they very rarely need to be written.

I think that last part is wrong in Python. Any time you are creating an 
immutable class -- and some of us do that a lot -- you generally need to write 
__new__. That makes __new__ very different from C++ allocators, and more like 
C++ constructors.

On the other hand, __new__ seems to be quite similar to ObjectiveC's `alloc`, 
which is called the allocator, and __init__ similar to ObjectiveC's init, which 
is the initialiser!

ObjectiveC also has a new method, which just calls alloc then init.


>> If the differences didn't matter I would agree that “overly pedantic” is
>> fair. But those differences trip up newcomers. Thinking of
>> ‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
>> from – am I not meant to be constructing it? — and to attempt to return
>> that instance.
> 
> Creating objects is confusing, but beginners don't come to Python
> with an expectation of what a "constructor" is.  Filling in the
> attributes of an object is just as clearly a kind of construction
> as allocating memory.


Remember that in Python __new__ can do a lot more than just allocate memory.

It just seems really weird to describe __init__ as a constructor when it 
initialises an existing instance: "initialiser" just seems to be the obvious 
term for it. (Do I really need to spell it out? __INIT__/INITialiser.)

Python's object creation model seems to be a lot closer to that of ObjectiveC 
or C++ than Javascript, so copying Javascript's terminology seems risky to me.



-- 
Steven
"Ever since I learned about confirmation bias, I've been seeing 
it everywhere." - Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Ned Batchelder
On Monday, December 12, 2016 at 6:17:43 PM UTC-5, Ben Finney wrote:
> Ned Batchelder  writes:
> 
> > Claiming that __init__ isn't a constructor seems overly pedantic to
> > me.
> 
> Whereas to me, claiming that ‘Foo.__init__’ is a constructor seems
> needlessly confusing.
> 
...
> * A constructor should return the instance. ‘Foo.__init__’ does not do
>   that; ‘Foo.__new__’ does.

This seems like an odd thing to insist on. C++ and Java constructors
don't return the instance.  C++ allocators return the instance. 
I'm happy to call __new__ an allocator. It serves exactly the same
role in Python as allocators do in C++: its job is to create the raw
material for the object, and they very rarely need to be written.

> 
> If the differences didn't matter I would agree that “overly pedantic” is
> fair. But those differences trip up newcomers. Thinking of
> ‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
> from – am I not meant to be constructing it? — and to attempt to return
> that instance.

Creating objects is confusing, but beginners don't come to Python
with an expectation of what a "constructor" is.  Filling in the 
attributes of an object is just as clearly a kind of construction
as allocating memory.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Chris Angelico
On Tue, Dec 13, 2016 at 10:17 AM, Ben Finney  wrote:
> If the differences didn't matter I would agree that “overly pedantic” is
> fair. But those differences trip up newcomers. Thinking of
> ‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
> from – am I not meant to be constructing it? — and to attempt to return
> that instance. And when the time comes to lean about ‘__new__’ the
> confusion continues, because the newcomer has been told that something
> *else* is the constructor, so what's this?

In JavaScript, it's normal to talk about "calling a function as a
constructor". When you do, there is a 'this' object before you start.
Should we tell the JavaScript folks to be more pedantic, because
'this' should end up existing? Does it really even matter when memory
gets allocated and the object's identity assigned? Before __init__
gets called, the object isn't "truly there" - its fundamental
invariants may not yet have been established, and key attributes might
not have been set up. Once __init__ finishes, there is an expectation
that attributes and invariants are sorted out.

This is like the old "Python doesn't have variables" thing.
Ultimately, every language has slightly different semantics (otherwise
they'd be trivial transformations, like Ook and Brainf*), so you have
to learn that the "constructor" might have slightly different
semantics. Accept it - embrace it. Learn it.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Ben Finney
Ned Batchelder  writes:

> Claiming that __init__ isn't a constructor seems overly pedantic to
> me.

Whereas to me, claiming that ‘Foo.__init__’ is a constructor seems
needlessly confusing.

* Classes already have a constructor, ‘Foo.__new__’. If we call
  something else the constructor, what do we call ‘__new__’? Are they
  both constructors?

* A constructor for Foo should start from “no instance” and result in
  “an instance of Foo”. ‘Foo.__init__’ does not do that; ‘Foo.__new__’
  does.

* A constructor should return the instance. ‘Foo.__init__’ does not do
  that; ‘Foo.__new__’ does.

If the differences didn't matter I would agree that “overly pedantic” is
fair. But those differences trip up newcomers. Thinking of
‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
from – am I not meant to be constructing it? — and to attempt to return
that instance. And when the time comes to lean about ‘__new__’ the
confusion continues, because the newcomer has been told that something
*else* is the constructor, so what's this?

> What's true is that Python's constructors (__init__) are different than
> C++ constructors.  In C++, you don't have an object of type T until the
> constructor has finished. In Python, you have an object of type T before
> __init__ has been entered.

I'm not going to argue that C++ should define terminology for other
languages. But “constructor” should have a close correlation with the
normal English-language meaning of the term.

That meaning matches ‘Foo.__new__’, which makes that method a
constructor. It does not match ‘Foo.__init__’, which makes that method
not a constructor.

> The reason to call __init__ a constructor is because of what is the
> same between C++ and Python: the constructor is where the author of
> the class can initialize instances of the class.

So you've just described what ‘Foo._init__’ does: it initialises the
existing instance. That's why it is better to call it the “initialiser”,
a term we already have and use correctly.

-- 
 \ “DRM doesn't inconvenience [lawbreakers] — indeed, over time it |
  `\ trains law-abiding users to become [lawbreakers] out of sheer |
_o__)frustration.” —Charles Stross, 2010-05-09 |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Steve D'Aprano
On Tue, 13 Dec 2016 07:15 am, Ned Batchelder wrote:

> Claiming that __init__ isn't a constructor seems overly pedantic to me.
> What's true is that Python's constructors (__init__) are different than
> C++ constructors.  In C++, you don't have an object of type T until the
> constructor has finished. In Python, you have an object of type T before
> __init__ has been entered.
> 
> The reason to call __init__ a constructor is because of what is the same
> between C++ and Python: the constructor is where the author of the class
> can initialize instances of the class.

That logic would have been more convincing back in the days of classic
classes in Python 1.5 or 2.0, less so after class/type unification where we
have an actual constructor __new__ that creates the instance.

The section of the docs that deal with object customization takes an
agnostic position, referring only to the "class constructor EXPRESSION"
(i.e. MyClass(spam, eggs) or equivalent):

https://docs.python.org/2/reference/datamodel.html#object.__init__

and similarly in __new__ (this time the v3 docs, just because):

https://docs.python.org/3/reference/datamodel.html#object.__new__


so if you want to be pedantic, one might argue that Python has a concept
of "object/class constructor expressions", MyClass(spam, eggs), but not of
constructor method(s). But that seems even stranger than insisting that:

- __new__ is the constructor method;
- __init__ is the initializer method.


Another way of naming things is to say that:

- __new__ is the allocator;
- __init__ is the initializer;
- the two together, __new__ + __init__, make up the constructor.

Not to be confused with the constructor expression, MyClass(spam, eggs), or
the alternative constructor, MyClass.make_instance(...).

Naming things is hard.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Juan C.
On Mon, Dec 12, 2016 at 6:59 PM, Thomas 'PointedEars' Lahn
 wrote:
> 

Using the Python official doc link you provided, it clearly states
that `__new__` is the one called to "create a new instance of class
[...] The return value of __new__() should be the new object instance
(usually an instance of cls)." On the other hand, `__init__` is
"called after the instance has been created (by __new__()), but before
it is returned to the caller."

Here we have the same mindset regarding `__new__` vs `__init__`:

- http://python-textbok.readthedocs.io/en/1.0/Classes.html
"Note: __init__ is sometimes called the object’s constructor, because
it is used similarly to the way that constructors are used in other
languages, but that is not technically correct – it’s better to call
it the initialiser. There is a different method called __new__ which
is more analogous to a constructor, but it is hardly ever used."

- http://www.python-course.eu/python3_object_oriented_programming.php
"We want to define the attributes of an instance right after its
creation. __init__ is a method which is immediately and automatically
called after an instance has been created. [...] The __init__ method
is used to initialize an instance."

- https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#Python
"In Python, constructors are defined by one or both of __new__ and
__init__ methods. A new instance is created by calling the class as if
it were a function, which calls the __new__ and __init__ methods. If a
constructor method is not defined in the class, the next one found in
the class's Method Resolution Order will be called."

- http://www.diveintopython3.net/iterators.html
"The __init__() method is called immediately after an instance of the
class is created. It would be tempting — but technically incorrect —
to call this the “constructor” of the class. It’s tempting, because it
looks like a C++ constructor (by convention, the __init__() method is
the first method defined for the class), acts like one (it’s the first
piece of code executed in a newly created instance of the class), and
even sounds like one. Incorrect, because the object has already been
constructed by the time the __init__() method is called, and you
already have a valid reference to the new instance of the class."


In general, the idea is simple, `__new__` constructs and `__init__`
initializes, this is what I believe in, after all the name `__init__`
already tell us that it's a *init* ialiser...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Ned Batchelder
On Monday, December 12, 2016 at 4:31:00 PM UTC-5, Gregory Ewing wrote:
> Ned Batchelder wrote:
> > In C++, you don't have an object of type T until the
> > constructor has finished. In Python, you have an object of type T before
> > __init__ has been entered.
> 
> That distinction seems a bit pedantic as well. Inside a C++
> constructor you have access to something having all the
> fields and methods of an object of type T, they just
> haven't been filled in yet.

I agree the distinction is pedantic. It does matter sometimes, such as:
if a C++ constructor raises an exception, will the corresponding destructor
be run, or not? (No, because it never finished making an object of type T.)

But in any case, all the more reason not to let C++ semantics govern
Python vocabulary.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Steve D'Aprano
On Tue, 13 Dec 2016 03:17 am, Chris Angelico wrote:

> You could check "foo" in self.__dict__, but I don't know of any
> real-world situations where you need to.

vars(self) is probably the better way to access self's namespace, rather
than directly self.__dict__. Unfortunately vars() doesn't understand
__slots__, which I think is an oversight.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Gregory Ewing

Ned Batchelder wrote:

In C++, you don't have an object of type T until the
constructor has finished. In Python, you have an object of type T before
__init__ has been entered.


That distinction seems a bit pedantic as well. Inside a C++
constructor you have access to something having all the
fields and methods of an object of type T, they just
haven't been filled in yet.

It's a bit like asking at what point between conception and
birth a baby starts to exist.

--
Greg

--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Thomas 'PointedEars' Lahn
Juan C. wrote:

> On Mon, Dec 12, 2016 at 12:34 PM, Thomas 'PointedEars' Lahn
>  wrote:
>> To call something means generally in programming, and in Python, to
>> execute it as a function instead: In the code above, the class object
>> referred to by “Box” is called twice in order to instantiate twice
>> (calling a class object in Python means to instantiate it, implicitly
>> calling its constructor method, “__init__”, if any), and the global
>> “print” function is called three times.
> 
> Since we are talking about Python terminology I believe that calling
> `__init__` a constructor is also wrong. I've already seem some
   ^
> discussions regarding it and the general consensus is that `__init__`
> shouldn't be called constructor as it isn't really a constructor (like
> Java/C# constructors). […]

IBTD:

,-
| 
| constructor
| 
| (programming)   1. In object-oriented languages, a function provided by a 
   
| class to initialise a newly created object. The constructor function 
  ^^
| typically has the same name as the class. It may take arguments, e.g. to 
| set various attributes of the object or it may just leave everything 
  
| undefined to be set elsewhere.
| 
| A class may also have a destructor function that is called when objects of 
| the class are destroyed.

Free On-line Dictionary of Computing, Last updated: 2014-10-04.

In Python, a class’s __init__() is called after its __new__() [1], and 
“typically” means “not always” (for another example, in clean PHP code the 
constructor’s name is “__construct”).



[In fact, there are constructors in object-oriented programming languages 
with prototype-based inheritance, like implementations of ECMAScript Ed. 1 
to 7 (except 4), too.]

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Ned Batchelder
On Monday, December 12, 2016 at 12:58:30 PM UTC-5, Juan C. wrote:
> Since we are talking about Python terminology I believe that calling
> `__init__` a constructor is also wrong. I've already seem some
> discussions regarding it and the general consensus is that `__init__`
> shouldn't be called constructor as it isn't really a constructor (like
> Java/C# constructors). Some source:
> 
> - 
> http://stackoverflow.com/questions/4859129/python-and-python-c-api-new-versus-init
> - http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init

Claiming that __init__ isn't a constructor seems overly pedantic to me.
What's true is that Python's constructors (__init__) are different than
C++ constructors.  In C++, you don't have an object of type T until the
constructor has finished. In Python, you have an object of type T before
__init__ has been entered.

The reason to call __init__ a constructor is because of what is the same
between C++ and Python: the constructor is where the author of the class
can initialize instances of the class.

There are many programming languages, and they have similar overlapping
constructs, but there are differences among the constructs.  It's a
challenge to decide when those differences are great enough to use a
different name, and when those differences are slight enough to just note
them as a difference.

As an example, people are happy to use the word "function" for things in
Python, C, C++, Java, JavaScript, and Haskell, despite the huge differences
in how they behave.  The commonalities, especially in how these constructs
are used by developers to express themselves, are similar enough that
we call them all "functions."  It seems to me that we can do the same
for "constructor."

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread John Gordon
In  "Juan C." 
 writes:

> The instructor said that the right way to call a class attribute is to use
> 'Class.class_attr' notation, but on the web I found examples where people
> used 'self.class_attr' to call class attributes.

Class instances may override class attributes by creating local attributes
of the same name, in which case Class.class_attr and self.class_attr may
not be equal, so you'd have to use the correct one for your needs.

If you're sure that an instance does not override the class attribute,
then you can use whichever one you prefer.  self.class_attr may be more
convenient because you don't have to provide a specific class name.

-- 
John Gordon   A is for Amy, who fell down the stairs
gor...@panix.com  B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Juan C.
On Mon, Dec 12, 2016 at 12:34 PM, Thomas 'PointedEars' Lahn
 wrote:
> First of all, the proper term for what you are doing there is _not_ “call”;
> you are _accessing_ an attribute instead.

Indeed, `accessing` seems better. I was looking for a better word but
couldn't find at the moment.

> To call something means generally in programming, and in Python, to execute
> it as a function instead: In the code above, the class object referred to by
> “Box” is called twice in order to instantiate twice (calling a class object
> in Python means to instantiate it, implicitly calling its constructor
> method, “__init__”, if any), and the global “print” function is called three
> times.

Since we are talking about Python terminology I believe that calling
`__init__` a constructor is also wrong. I've already seem some
discussions regarding it and the general consensus is that `__init__`
shouldn't be called constructor as it isn't really a constructor (like
Java/C# constructors). Some source:

- 
http://stackoverflow.com/questions/4859129/python-and-python-c-api-new-versus-init
- http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Juan C.
On Sun, Dec 11, 2016 at 11:34 PM, Steve D'Aprano
 wrote:

> So... in summary:
>
>
> When *assigning* to an attribute:
>
> - use `self.attribute = ...` when you want an instance attribute;
>
> - use `Class.attribute = ...` when you want a class attribute in
>   the same class regardless of which subclass is being used;
>
> - use `type(self).attribute = ...` when you want a class attribute
>   in a subclass-friendly way.
>
>
> When *retrieving* an attribute:
>
> - use `self.attribute` when you want to use the normal inheritance
>   rules are get the instance attribute if it exists, otherwise a
>   class or superclass attribute;
>
> - use `type(self).attribute` when you want to skip the instance
>   and always return the class or superclass attribute.

Thanks, that seems simple enough.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Chris Angelico
On Tue, Dec 13, 2016 at 1:34 AM, Thomas 'PointedEars' Lahn
 wrote:
> ³  How can one tell the difference in Python between a pre-initialized,
>inherited attribute value and one own that is just equal to the inherited
>one?  In ECMAScript, this.hasOwnProperty("foo") would return “false” if
>the property were inherited, “true” otherwise.  But in Python,
>hasattr(self, "foo") returns “True” regardless whether the “foo”
>attribute of the calling instance has been assigned a value explicitly.
>What is the Python equivalent of ECMAScript’s
>Object.prototype.hasOwnProperty() method?

You could check "foo" in self.__dict__, but I don't know of any
real-world situations where you need to.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Thomas 'PointedEars' Lahn
Thomas 'PointedEars' Lahn wrote:

> Note that (AIUI) in this example the instances of the class referred by
> “C” do not have an *own* “foo” property in the beginning, so until bar()
> is called on them, they inherit that property (and its value) from that
> class.³

For proper *Python* terminology, s/property/attribute/g here (see below).

> […]
> 
> […]
> ³  How can one tell the difference in Python between a pre-initialized,
>inherited attribute value and one own that is just equal to the
>inherited one?  In ECMAScript, this.hasOwnProperty("foo") would return
>“false” if the property were inherited, “true” otherwise.  But in
>Python, hasattr(self, "foo") returns “True” regardless whether the
>“foo” attribute of the calling instance has been assigned a value
>explicitly.  What is the Python equivalent of ECMAScript’s
>Object.prototype.hasOwnProperty() method?

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-12 Thread Thomas 'PointedEars' Lahn
Juan C. wrote:

> I'm watching a Python course and was presented a topic regarding classes.
> One of the examples were:
> 
> box.py
> 
> class Box:
> serial = 100
> 
> def __init__(self, from_addr, to_addr):
> self.from_addr = from_addr
> self.to_addr = to_addr
> self.serial = Box.serial
> Box.serial += 1
> 
> 
> from box import *
> 
> a = Box('19 Beech Ave. Seattle, WA 98144', '49 Carpenter Street North
> Brunswick, NJ 08902')
> b = Box('68 N. Church Dr. Vicksburg, MS 39180', '8 Lake Forest Road
> Princeton, NJ 08540')
> 
> print(a.serial)  # print: 100
> print(b.serial)  # print: 101
> print(Box.serial)  # print: 102
> 
> 
> The instructor said that the right way to call a class attribute is to use
> 'Class.class_attr' notation, but on the web I found examples where people
> used 'self.class_attr' to call class attributes. I believe that using the
> first notation is better ('Class.class_attr'), this way the code is more
> explicit, but is there any rules regarding it?

First of all, the proper term for what you are doing there is _not_ “call”;  
you are _accessing_ an attribute instead.

To call something means generally in programming, and in Python, to execute 
it as a function instead: In the code above, the class object referred to by 
“Box” is called twice in order to instantiate twice (calling a class object 
in Python means to instantiate it, implicitly calling its constructor 
method, “__init__”, if any), and the global “print” function is called three 
times.

Second, you do not appear to be aware that the notations

  C.foo

and

  self.foo

within a method of the class object referred to by “C” are _not_ equivalent:

“C” is _not_ a "more explicit" way to access the class than “self”; it is 
referring to a *different* (type of) *object* instead, a *class* object.  
(This is different in Python than in, for example, PHP.)

Assignment to “C.foo” modifies an attribute named “foo” of the class object 
referred to “C”, i.e. it modifies the value of that attribute *for all 
instances of that class* (but see below).

Assignment to “self.foo” modifies only the “foo” attribute *of a particular 
instance* of the class, or adds an attribute of that name to it; namely, the 
instance on which the method was called that modifies/adds the “foo” 
attribute (referred to by the formal parameter “self” of the method¹).

$ python3 -c '
class C:
foo = 23

def bar (self):
self.foo = 42

def baz (self):
C.foo = 42

print(C.foo)
o = C()
o2 = C()   
print(C.foo, o.foo, o2.foo)
o.bar()
print(C.foo, o.foo, o2.foo)
o.baz()
print(C.foo, o.foo, o2.foo)
'
23
23 23 23
23 42 23
42 42 42


To illustrate, the (simplified) UML diagrams² for the state of the program 
after each relevant executed chunk of code (as always recommended, use a 
fixed-width font for display):

#
class C:
foo = 23

def bar (self):
self.foo = 42

def baz (self):
C.foo = 42

#

  ,-.
C --> : :type   :
  :=:
  : +foo : int = 23 :
  :-:
  : +bar()  :
  : +baz()  :
  `-'

#
o = C()
#

  ,-.
C --> : :type   :
  :=:
  : +foo : int = 23 :
  :-:
  : +bar()  :
  : +baz()  :
  `-'
   ^
   :
,-.
o > : :__main__.C :
:-:
`-'

#
o2 = C()   
#

,---.
C > : :type :
:===:
: +foo : int = 23   :
:---:
: +bar():
: +baz():
`---'
  ^   ^   
  :   :
   ,-. ,-.
o ---> : :__main__.C : : :__main__.C : <--- o2
   :-: :-:
   `-' `-'

#
o.bar()
#

,-.
C > : :type   :
:=:
: +foo : int = 23 :
:-:
: +bar()  :
: +baz()  :
`-'
^ ^
: :
   ,-. ,-.
o ---> : 

Re: The right way to 'call' a class attribute inside the same class

2016-12-11 Thread Steve D'Aprano
On Mon, 12 Dec 2016 07:10 am, Juan C. wrote:

> I'm watching a Python course and was presented a topic regarding classes.
> One of the examples were:
> 
> box.py
> 
> class Box:
> serial = 100
> 
> def __init__(self, from_addr, to_addr):
> self.from_addr = from_addr
> self.to_addr = to_addr
> self.serial = Box.serial
> Box.serial += 1


If you want to distinguish between an instance attribute and a class
attribute, you must specify the instance or the class:

self.serial # may be the instance attribute, or the class attribute
Box.serial  # always the class attribute


But what happens inside a subclass?

class BoxWithLid(Box):
pass

Generally we expect methods called from the subclass BoxWithLid to refer to
the BoxWithLid attribute, not the Box attribute. So Box.serial will be
wrong when the method is called from a subclass.

type(self).serial  # still correct when called from a subclass

> The instructor said that the right way to call a class attribute is to use
> 'Class.class_attr' notation, 

That is nearly always wrong, since it will break when you subclass. If you
do that, you should document that the class is not expected to be
subclasses, and may not work correctly if you do.


> but on the web I found examples where people 
> used 'self.class_attr' to call class attributes. I believe that using the
> first notation is better ('Class.class_attr'), this way the code is more
> explicit, but is there any rules regarding it?

Assignment to self.serial will always create or affect an instance
attribute. But merely retrieving self.serial will use inheritance to try
returning the instance attribute *if it exists*, and if not, fall back on
the class attribute (or a superclass).

This is especially useful for read-only defaults, constants or configuration
settings.


class Document:
page_size = A4

def page_area(self):
dimensions = list(self.page_size)
dimensions[0] -= self.left_margin
dimensions[1] -= self.right_margin
dimensions[2] -= self.top_margin
dimensions[3] -= self.bottom_margin
return dimensions


doc = Document()  # uses the default page size of A4

doc.page_size = Foolscape  # override the default


It is a matter of taste and context whether you do this, or the more
conventional way:

class Document:
def __init__(self):
self.page_size = A4


Use whichever is better for your specific class.


So... in summary:


When *assigning* to an attribute:

- use `self.attribute = ...` when you want an instance attribute;

- use `Class.attribute = ...` when you want a class attribute in 
  the same class regardless of which subclass is being used;

- use `type(self).attribute = ...` when you want a class attribute
  in a subclass-friendly way.


When *retrieving* an attribute:

- use `self.attribute` when you want to use the normal inheritance
  rules are get the instance attribute if it exists, otherwise a
  class or superclass attribute;

- use `type(self).attribute` when you want to skip the instance
  and always return the class or superclass attribute.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-11 Thread Terry Reedy

On 12/11/2016 5:29 PM, Gregory Ewing wrote:

Juan C. wrote:

The instructor said that the right way to call a class attribute is to
use
'Class.class_attr' notation, but on the web I found examples where people
used 'self.class_attr' to call class attributes. I believe that using the
first notation is better ('Class.class_attr'), this way the code is more
explicit, but is there any rules regarding it?


Yes. Use the form appropriate to the situation.  In other words, use 
open-eyed rule, not a closed-eye rule.  This applies to much of Python 
programming and programming is general.  Greg nicely explains the 
application of this rule.



It depends on how the class attribute is being used.

If you're only reading the attribute, either way will work.
Which one is more appropriate depends on what the attribute
is used for. Often a class attribute is used as a default
value for an instance attribute, in which case accessing it
via the instance is entirely appropriate.


The use of a (constant) class attribute as default instance attribute 
might be an optimization added after the first version of the class, or 
one that could disappear in the future.


> On the other

hand, if it's truly mean to be an attribute of the class
itself, accessing it via the class is probably clearer.

If the attribute is being written, you don't have any
choice. If you want to rebind the attribute in the class,
you have to access it via the class. This is the case
for this line in your example:

Box.serial += 1

If instead you did 'self.serial += 1' it would create
a new instance attribute shadowing the class attribute,
and the class attribute would remain bound to its
previous value.


I agree with the other post suggesting using 'next_serial' as the class 
attribute, as that is what the class attribute is.  I would access it as 
Box.serial.


Instance methods should normal be accessed through an instance, though 
there are exceptions.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-11 Thread Gregory Ewing

Juan C. wrote:

The instructor said that the right way to call a class attribute is to use
'Class.class_attr' notation, but on the web I found examples where people
used 'self.class_attr' to call class attributes. I believe that using the
first notation is better ('Class.class_attr'), this way the code is more
explicit, but is there any rules regarding it?


It depends on how the class attribute is being used.

If you're only reading the attribute, either way will work.
Which one is more appropriate depends on what the attribute
is used for. Often a class attribute is used as a default
value for an instance attribute, in which case accessing it
via the instance is entirely appropriate. On the other
hand, if it's truly mean to be an attribute of the class
itself, accessing it via the class is probably clearer.

If the attribute is being written, you don't have any
choice. If you want to rebind the attribute in the class,
you have to access it via the class. This is the case
for this line in your example:

Box.serial += 1

If instead you did 'self.serial += 1' it would create
a new instance attribute shadowing the class attribute,
and the class attribute would remain bound to its
previous value.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: The right way to 'call' a class attribute inside the same class

2016-12-11 Thread Chris Angelico
On Mon, Dec 12, 2016 at 7:10 AM, Juan C.  wrote:
> class Box:
> serial = 100
>
> def __init__(self, from_addr, to_addr):
> self.from_addr = from_addr
> self.to_addr = to_addr
> self.serial = Box.serial
> Box.serial += 1
>

I would say that this is awkward usage; the class attribute isn't
being used as a default for the instance, it's being used as "the next
one". I would rename the class attribute to "next_serial". That would
give you the freedom to use whichever notation you like, as there
won't be a conflict.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list