Re: [Tutor] Good approach regarding classes attributes

2014-09-11 Thread Danny Yoo
> I've just again experienced a new employer that tells my students my
> name is 'Van Den Broek' when I tell them that it is 'van den Broek.'
> This is the third time this week I've encountered this as a
> programming example. Perhaps the use of the example is responsible for
> the false belief amongst programmers that a surname always starts with
> a captial letter. (Also delightful is the view that no name can
> contain spaces.)
>

My apologies!  I'll try a different example next time using strip() to
remove surrounding whitespace.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-11 Thread Brian van den Broek
On 7 September 2014 21:01, Danny Yoo  wrote:



> Let's use a concrete example: say that we'd like to make sure a
> Person's name is always capitalized.  We might try to enforce this
> capitalization property in the constructor.


Hi all,



I've just again experienced a new employer that tells my students my
name is 'Van Den Broek' when I tell them that it is 'van den Broek.'
This is the third time this week I've encountered this as a
programming example. Perhaps the use of the example is responsible for
the false belief amongst programmers that a surname always starts with
a captial letter. (Also delightful is the view that no name can
contain spaces.)

For the love of puppies, can people please stop using this example?!



(Apologies to Danny; as the other two cases I saw recently were in
books, it was easiest to lash out against this example.)

notVanDenly yours,

Brian vdB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Alan Gauld

On 09/09/14 14:44, Peter Otten wrote:


Is it not helpful to always put (object) as the parent, if the class is
not itself a sub-class?


The answer differs between Python 2 and 3. In Python 3

class C: # preferred in Python 3
 pass



Apologies, I should have mentioned that. I've been using Python3 almost 
exclusively since January this year and I'm starting to forget my Python 
2 idioms...



--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Sydney Shall

On 09/09/2014 16:05, Joel Goldstick wrote:

On Tue, Sep 9, 2014 at 10:02 AM, Sydney Shall  wrote:

On 09/09/2014 15:44, Peter Otten wrote:

Sydney Shall wrote:

On 08/09/2014 18:39, Alan Gauld wrote:

On 08/09/14 15:17, Juan Christian wrote:

One tiny tweak...

class User():

You don't need the parens after User. You don;t have any superclasses
so they do nothing. Python convention for an empty parent list is just
to leave the parens off:

class User:

A simple question from a newbie, in response to this surprise.
Is it not helpful to always put (object) as the parent, if the class is
not itself a sub-class?

The answer differs between Python 2 and 3. In Python 3

class C: # preferred in Python 3
 pass

and

class C(object):
 pass

are the same, so there is no point adding the explicit object inheritance.

In Python 2 however

class C:
 pass

will create a "classic class" whereas

class C(object): # preferred in Python 2
 pass

is a "newstyle class". The most notable difference between these is that
properties work correctly only with newstyle classes. Therefore making all
your classes "newstyle" is a good idea.

And while I am writing, what does OP stand for in this list?

Original Poster, as Leam says.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Thanks Peter, most helpful.
I was taught with Python 2.7, so  now I understand the advice.


--
Sydney Shall

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Please post in plain text


My apologies. I thought I was. I will immediately change it.

--
Sydney Shall
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Joel Goldstick
On Tue, Sep 9, 2014 at 10:02 AM, Sydney Shall  wrote:
> On 09/09/2014 15:44, Peter Otten wrote:
>
> Sydney Shall wrote:
>
> On 08/09/2014 18:39, Alan Gauld wrote:
>
> On 08/09/14 15:17, Juan Christian wrote:
>
> One tiny tweak...
>
> class User():
>
> You don't need the parens after User. You don;t have any superclasses
> so they do nothing. Python convention for an empty parent list is just
> to leave the parens off:
>
> class User:
>
> A simple question from a newbie, in response to this surprise.
> Is it not helpful to always put (object) as the parent, if the class is
> not itself a sub-class?
>
> The answer differs between Python 2 and 3. In Python 3
>
> class C: # preferred in Python 3
> pass
>
> and
>
> class C(object):
> pass
>
> are the same, so there is no point adding the explicit object inheritance.
>
> In Python 2 however
>
> class C:
> pass
>
> will create a "classic class" whereas
>
> class C(object): # preferred in Python 2
> pass
>
> is a "newstyle class". The most notable difference between these is that
> properties work correctly only with newstyle classes. Therefore making all
> your classes "newstyle" is a good idea.
>
> And while I am writing, what does OP stand for in this list?
>
> Original Poster, as Leam says.
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
> Thanks Peter, most helpful.
> I was taught with Python 2.7, so  now I understand the advice.
>
>
> --
> Sydney Shall
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

Please post in plain text

-- 
Joel Goldstick
http://joelgoldstick.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Sydney Shall

On 09/09/2014 15:44, Peter Otten wrote:

Sydney Shall wrote:


On 08/09/2014 18:39, Alan Gauld wrote:

On 08/09/14 15:17, Juan Christian wrote:

One tiny tweak...


class User():

You don't need the parens after User. You don;t have any superclasses
so they do nothing. Python convention for an empty parent list is just
to leave the parens off:

class User:


A simple question from a newbie, in response to this surprise.
Is it not helpful to always put (object) as the parent, if the class is
not itself a sub-class?

The answer differs between Python 2 and 3. In Python 3

class C: # preferred in Python 3
 pass

and

class C(object):
 pass

are the same, so there is no point adding the explicit object inheritance.

In Python 2 however

class C:
 pass

will create a "classic class" whereas

class C(object): # preferred in Python 2
 pass

is a "newstyle class". The most notable difference between these is that
properties work correctly only with newstyle classes. Therefore making all
your classes "newstyle" is a good idea.


And while I am writing, what does OP stand for in this list?

Original Poster, as Leam says.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Thanks Peter, most helpful.
I was taught with Python 2.7, so  now I understand the advice.


--
Sydney Shall
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Juan Christian
On Mon, Sep 8, 2014 at 5:58 AM, Peter Otten <__pete...@web.de >
wrote:

>
> PS: This is not about being pythonic, but it might be more convenient for
> client code if you use datetime objects instead of timestamps:
>
> >>> import datetime
> >>> last_logoff = datetime.datetime.utcfromtimestamp(1410065399)
> >>> print(last_logoff)
> 2014-09-07 04:49:59
>

Yes, I'll do it for sure, the API response is indeed returned that way to
make things easier.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Peter Otten
Sydney Shall wrote:

> On 08/09/2014 18:39, Alan Gauld wrote:
>> On 08/09/14 15:17, Juan Christian wrote:
>>
>> One tiny tweak...
>>
>>> class User():
>>
>> You don't need the parens after User. You don;t have any superclasses
>> so they do nothing. Python convention for an empty parent list is just
>> to leave the parens off:
>>
>> class User:
>>
> A simple question from a newbie, in response to this surprise.
> Is it not helpful to always put (object) as the parent, if the class is
> not itself a sub-class?

The answer differs between Python 2 and 3. In Python 3

class C: # preferred in Python 3
pass

and

class C(object): 
pass

are the same, so there is no point adding the explicit object inheritance.

In Python 2 however

class C: 
pass

will create a "classic class" whereas

class C(object): # preferred in Python 2
pass

is a "newstyle class". The most notable difference between these is that 
properties work correctly only with newstyle classes. Therefore making all 
your classes "newstyle" is a good idea.

> And while I am writing, what does OP stand for in this list?

Original Poster, as Leam says. 


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread leam hall
On Tue, Sep 9, 2014 at 9:09 AM, Sydney Shall  wrote:

> And while I am writing, what does OP stand for in this list?

"Original Poster". So I understand. Won't answer the Python question
since I'm a newbie here myself.

-- 
Mind on a Mission
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-09 Thread Sydney Shall

On 08/09/2014 18:39, Alan Gauld wrote:

On 08/09/14 15:17, Juan Christian wrote:

One tiny tweak...


class User():


You don't need the parens after User. You don;t have any superclasses 
so they do nothing. Python convention for an empty parent list is just 
to leave the parens off:


class User:


A simple question from a newbie, in response to this surprise.
Is it not helpful to always put (object) as the parent, if the class is 
not itself a sub-class?

And while I am writing, what does OP stand for in this list?


--
Sydney Shall
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Peter Otten
Juan Christian wrote:

>>
>> > On Mon, Sep 8, 2014 at 5:58 AM, Peter Otten <__pete...@web.de> wrote:
>>
>> In that spirit here's an alternative implementation of the User class:
>>
>> from collections import namedtuple
>> User = namedtuple(
>> "User",
>> "steamid personaname lastlogoff profileurl "
>> "avatar timecreated countrycode")
>>
>> You may note that I refrained from making little improvements to the
>> attribute names -- another odd preference of mine ;) -- which also helps
>> simplify the fetch_users() implementation:
>>
>> ...
>> for user in user_list:
>> if user["communityvisibilitystate"] == 3:
>> users.append(User._make(user[field] for field in User._fields))
>> ...
> 
> 
> I didn't get the idea behind 'namedtuple' and your 'User._make(user[field]
> for field in User._fields)', I'm still using the other way:
> 
> import urllib.request
> import json
> 
> class User:
> 
> def __init__(self, steamid, personaname, lastlogoff, profileurl, avatar,
> timecreated, loccountrycode):
> self.steam_id = steamid
> self.persona_name = personaname
> self.last_logoff = lastlogoff
> self.profile_url = profileurl
> self.avatar = avatar
> self.time_created = timecreated
> self.country_code = loccountrycode
> 
> def fetch_users(*steamids):
> users = []
> 
> req = urllib.request.urlopen('
> 
http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=B9X20&steamids='
> + ','.join(steamids))
> user_list = json.loads(req.read().decode('utf-8'))["response"]["players"]
> 
> for user in user_list:
> if user["communityvisibilitystate"] == 3:
> users.append(User(user["steamid"], user["personaname"],
> user["lastlogoff"], user["profileurl"], user["avatar"],
> user["timecreated"], user["loccountrycode"]))
> 
> return users
> 
> As you guys said, I'd better use the "all open" pythonic way and not try
> to hide things, so here it's. Is this piece of code pythonic enough?

Yes, I think this is simple enough that you can easily understand it when 
you look at it again in a year. There are no constructs that strike me as 
unidiomatic.

It's time to stop pondering over the innards of this component and use it to 
build something useful. Good luck with that!


PS: This is not about being pythonic, but it might be more convenient for 
client code if you use datetime objects instead of timestamps:

>>> import datetime
>>> last_logoff = datetime.datetime.utcfromtimestamp(1410065399)
>>> print(last_logoff)
2014-09-07 04:49:59


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Juan Christian
>
> > On Mon, Sep 8, 2014 at 5:58 AM, Peter Otten <__pete...@web.de> wrote:
>
> In that spirit here's an alternative implementation of the User class:
>
> from collections import namedtuple
> User = namedtuple(
> "User",
> "steamid personaname lastlogoff profileurl "
> "avatar timecreated countrycode")
>
> You may note that I refrained from making little improvements to the
> attribute names -- another odd preference of mine ;) -- which also helps
> simplify the fetch_users() implementation:
>
> ...
> for user in user_list:
> if user["communityvisibilitystate"] == 3:
> users.append(User._make(user[field] for field in User._fields))
> ...


I didn't get the idea behind 'namedtuple' and your 'User._make(user[field]
for field in User._fields)', I'm still using the other way:

import urllib.request
import json

class User:

def __init__(self, steamid, personaname, lastlogoff, profileurl, avatar,
timecreated, loccountrycode):
self.steam_id = steamid
self.persona_name = personaname
self.last_logoff = lastlogoff
self.profile_url = profileurl
self.avatar = avatar
self.time_created = timecreated
self.country_code = loccountrycode

def fetch_users(*steamids):
users = []

req = urllib.request.urlopen('
http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=B9X20&steamids='
+ ','.join(steamids))
user_list = json.loads(req.read().decode('utf-8'))["response"]["players"]

for user in user_list:
if user["communityvisibilitystate"] == 3:
users.append(User(user["steamid"], user["personaname"], user["lastlogoff"],
user["profileurl"], user["avatar"], user["timecreated"],
user["loccountrycode"]))

return users

As you guys said, I'd better use the "all open" pythonic way and not try to
hide things, so here it's. Is this piece of code pythonic enough?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Alan Gauld

On 08/09/14 15:17, Juan Christian wrote:


Why normal attributes? Isn't it better to make these read-only as I won't
ever need to modify them? And even if I modify them, it won't change in the
Steam servers, only in my program, and I don't see any use for that, I need
the 'real' values always, the 'real' thing only.


Read  only is not a good term for properties, they are not really 
read-only. You can still change the unmderlying attribute directly:


>>> class C:
...def __init__(self,x):
...  self._x = x
...@property
...def x(self):
...  return self._x
...
>>> c = C(66)
>>> c.x
66
>>> c._x
66
>>> c.x = 22
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: can't set attribute
>>> c._x = 22
>>> c.x
22


Notice that although I can't set x, I can set _x!
And it 'changes' x.

The only thing that stops me is seeing the _x which
tells me I shouldn't be messing with it.

So in this scenario the property only buys you a tiny bit of protection, 
you are really still relying on the "We are all

consenting adults" philosophy of Python...

That's why we would normally only use normal attributes
unless the property needed some munging inside the
getter/setter method.

If you really really don't trust your clients not to mess
with _x then that's where you probably do need the __x version, combined 
with properties. which is where we came in! :-)

(And its still not 100% foolproof)

>>> class C:
...def __init__(self,x):
...  self.__x = x
...@property
...def x(self):
...  return self.__x
...
>>> c = C(66)
>>> c.x
66
>>> c.__x
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'C' object has no attribute '__x'
>>> c.x = 22
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: can't set attribute
>>> c.__x = 22
>>> c.x
66
>>> c.__x
22

Notice I can still set/read __x from the client,
but at least this time it does not change
the x property value...

>>> dir(c)
['_C__x', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', 
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', 
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', '__x', 'x']

>>>

Notice dir() shows that you now have two __x attributes, the original 
name-mangled version and the new local 'c' instance version.


The only way to get total read-only working would be to write your own 
get attribute function - I think that is as near foolproof as you can 
get in Python.


Python doesn't really make this kind of data hiding easy, its just
not the Pythonic way. Python is not Java (or Smalltalk for that
matter).

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Alan Gauld

On 08/09/14 15:17, Juan Christian wrote:

One tiny tweak...


class User():


You don't need the parens after User. You don;t have any superclasses so 
they do nothing. Python convention for an empty parent list is just to 
leave the parens off:


class User:

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Peter Otten
Juan Christian wrote:

> On Mon, Sep 8, 2014 at 5:58 AM, Peter Otten <__pete...@web.de> wrote:

>> Personally I'd use normal attributes, though.
>>
> 
> Why normal attributes? Isn't it better to make these read-only as I won't
> ever need to modify them? And even if I modify them, it won't change in
> the Steam servers, only in my program, and I don't see any use for that, I
> need the 'real' values always, the 'real' thing only.

Yes, but you know that those attributes should not be reassigned, and for 
everyone else a hint in the docstring will do. Basically I tend to write as 
little code as needed, or to put it another way: I'm a lazy bastard ;)

In that spirit here's an alternative implementation of the User class:

from collections import namedtuple
User = namedtuple(
"User",
"steamid personaname lastlogoff profileurl "
"avatar timecreated countrycode")

You may note that I refrained from making little improvements to the 
attribute names -- another odd preference of mine ;) -- which also helps 
simplify the fetch_users() implementation:

...
for user in user_list:
if user["communityvisibilitystate"] == 3:
users.append(User._make(user[field] for field in User._fields))
...

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Juan Christian
On Mon, Sep 8, 2014 at 5:58 AM, Peter Otten <__pete...@web.de> wrote:
>
>
> Personally I'd use normal attributes, though.
>

Why normal attributes? Isn't it better to make these read-only as I won't
ever need to modify them? And even if I modify them, it won't change in the
Steam servers, only in my program, and I don't see any use for that, I need
the 'real' values always, the 'real' thing only.


 On Mon, Sep 8, 2014 at 2:36 AM, Alan Gauld 
 wrote:

>
> Also note the underscore. It improves readability to break multi-words
> like that.
> For example several others have quoted this as 'person name' rather than
> 'persona name' - quite a different concept but hard to spot when all one
> word...


I tried to follow the variables from the Steam API, there they use
'personaname', 'lastlogoff', 'profileurl', 'loccountrycode' and so on,
everything without ' _ ', but now I'm doing the way you said, thanks!


   File "D:\Documents\HomeBroker\user.py", line 11, in __init__
>>  self._avatar = avatar
>> AttributeError: can't set attribute
>>
>
> Thats because you set the property name to the field name.
> Notice the difference:
>
> @property
> def profileurl(self):
> return self._profileurl
>
> @property
> def _avatar(self):
> return self._avatar
>
>
> The first sets the property to the non-underscore version
> The second uses underscore for both property and field name,
> thus making the field read-only. Be careful what you wish for...
>
> Another reason to only use properties when you *need* to
> make them read only (or to do some processing on reads
> or writes)


Yes, my fault there, I didn't see the ' _ ' in the beginning of the
function, but I do need them to be read-only, the user will never need to
modify them, and if he tries to modify let's say the name, ' persona_name =
"New Name Here" ', it would only change inside the program, the Steam
Servers would still use the old name, the 'real' name.


The new and now working code is the following:

import urllib.request
import json

class User():

def __init__(self, steamid, personaname, lastlogoff, profileurl, avatar,
timecreated, loccountrycode):
self._steam_id = steamid
self._persona_name = personaname
self._last_logoff = lastlogoff
self._profile_url = profileurl
self._avatar = avatar
self._time_created = timecreated
self._country_code = loccountrycode


@property
def steam_id(self):
return self._steam_id

@property
def persona_name(self):
return self._persona_name

@property
def last_logoff(self):
return self._last_logoff

@property
def profile_url(self):
return self._profile_url

@property
def avatar(self):
return self._avatar

@property
def time_created(self):
return self._time_created

@property
def country_code(self):
return self._country_code


def fetch_users(*id_collection):
steamid = []
users = []

for user_id in id_collection:
steamid.append(user_id)

req = urllib.request.urlopen('
http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=B9FXD20&steamids='
+ ','.join(steamid))
user_list = json.loads(req.read().decode('utf-8'))["response"]["players"]

for user in user_list:
if user["communityvisibilitystate"] == 3: # Only people with open profile
and inventory are wanted
users.append(User(user["steamid"], user["personaname"], user["lastlogoff"],
user["profileurl"], user["avatar"], user["timecreated"],
user["loccountrycode"]))

return users


Remember that I do need these attributes to be read-only, so I need to use
the '@property' decoration. I modified the 'fetch_users' function in order
to accept any number of IDs, this way I can fetch various profiles in one
call. Any problems, suggestions now?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-08 Thread Peter Otten
Juan Christian wrote:


> I'll definitely use the '@property' decoration. Thanks for the tip, 

Personally I'd use normal attributes, though.

> so, a
> different module to accommodate all the API requests and one for the
> logic/code itself is a better approach, right?

A separate function or method should be sufficient.

> Creating new users won't exist, my program is like a Home Broker using the
> Steam API. This 'User' class will be mainly used to properly store the
> users data, I'll automatically and recursively go trough my (or any
> person) friend-list and fetch users info and inventory and properly use it
> in my favor.

It is always a good idea to give such background right from the start. There 
are existing wrappers of that API. You might adopt one or at least have a 
look at the code to see how they are solving the issues you encounter.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Alan Gauld

On 08/09/14 03:31, Juan Christian wrote:


@property
def steamid(self):
 return self._steamid


Unless you specifically *need* these fields to be read-only you don't 
need the property declarations.


Just use the _XXX convention to signal that they are *intended*
to be private and allow clients to access them as myuser._persona_name

Also note the underscore. It improves readability to break multi-words 
like that.
For example several others have quoted this as 'person name' rather than 
'persona name' - quite a different concept but hard to spot when all one 
word...



   File "D:\Documents\HomeBroker\user.py", line 11, in __init__
 self._avatar = avatar
AttributeError: can't set attribute


Thats because you set the property name to the field name.
Notice the difference:

@property
def profileurl(self):
return self._profileurl

@property
def _avatar(self):
return self._avatar


The first sets the property to the non-underscore version
The second uses underscore for both property and field name,
thus making the field read-only. Be careful what you wish for...

Another reason to only use properties when you *need* to
make them read only (or to do some processing on reads
or writes)

HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Danny Yoo
 @property
 def _avatar(self):
 return self._avatar
>>
>> Hi Joel,
>>
>> The above code looks strange to me.  The method and the field name
>> should not use the same name.
>
> ah! good catch Danny.  I didn't write it, I was commenting on the OP code.
>
> But (and maybe this was discussed earlier in the thread), what value
> is using the property decorator instead of just saving the data to
> attributes?


Let's first point to documentation that says what "property" is:

   https://docs.python.org/2/library/functions.html#property

If you read it a bit, one of the key terms that should come up is
"managed attribute".

What do they mean by this?

A managed attribute is an attribute that the class's definition
actively controls.

Let's use a concrete example: say that we'd like to make sure a
Person's name is always capitalized.  We might try to enforce this
capitalization property in the constructor.

###
class Person(object):
def __init__(self, name):
self.name = name.title()
def greet(self):
print("Hi, I'm %s" % self.name)

p = Person("joel goldstick")
p.greet()
###

However, this does not stop clients from assigning directly to the name,

#
p.name = "joel goldstick"
#

and therefore breaking a desire to keep the name capitalized.  So this
might be a problem.

So what we'd like is the following: to make sure that there's some
kind of program logic that kicks in whenever we assign to Person.name.

In some programming languages, we do this by marking the attribute
name in some way that makes it clear not to access it directly, and we
provide "setter" and "getter" methods, the code that can "manage" this
attribute.

#
class Person(object):
def __init__(self, name):
self._name = name.title()

def getName(self):
return self._name

def setName(self, name):
self._name = name.title()

def greet(self):
print("Hi, I'm %s" % self._name)

## client code:
p = Person("joel goldstick")
print(p.getName())
p.greet()

p.setName("juan christian")
print(p.getName())
p.greet()
#


Python allows us to get "setter" and "getter"-like behavior while
still allowing client code to use the attribute with what looks like
direct attribute access:

#
class Person(object):
def __init__(self, name):
self._name = name.title()

@property
def name(self):
return self._name

@name.setter
def name(self, newName):
self._name = newName.title()

def greet(self):
print("Hi, I'm %s" % self._name)

## client code:
p = Person("joel goldstick")
print(p.name)
p.greet()

p.name= "juan christian"
print(p.name)
p.greet()
#

where now the client code looks simpler, but the class definition
still gets to manage the attribute's value.


Hopefully that helps to make the suggestions in this thread a little
more understandable in context.  Python's properties allow us to make
the client code look direct but still allow for attribute management.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Joel Goldstick
On Sun, Sep 7, 2014 at 11:01 PM, Danny Yoo  wrote:
>>> @property
>>> def _avatar(self):
>>> return self._avatar
>
> Hi Joel,
>
> The above code looks strange to me.  The method and the field name
> should not use the same name.

ah! good catch Danny.  I didn't write it, I was commenting on the OP code.

But (and maybe this was discussed earlier in the thread), what value
is using the property decorator instead of just saving the data to
attributes?



-- 
Joel Goldstick
http://joelgoldstick.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Danny Yoo
>> @property
>> def _avatar(self):
>> return self._avatar

Hi Joel,

The above code looks strange to me.  The method and the field name
should not use the same name.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Joel Goldstick
On Sun, Sep 7, 2014 at 10:31 PM, Juan Christian
 wrote:
> So... I tried to follow all what you guys said:
>
> user.py module:
>
> import urllib.request
> import json
>
> class User():
>
> def __init__(self, steamid, personaname, lastlogoff, profileurl, avatar,
> timecreated, loccountrycode):
> self._steamid = steamid
> self._personaname = personaname
> self._lastlogoff = lastlogoff
> self._profileurl = profileurl
> self._avatar = avatar
> self._timecreated = timecreated
> self._loccountrycode = loccountrycode
>
>
> @property
> def steamid(self):
>return self._steamid

I don't understand the purpose of the decorator and the _business
why not self.timecreated = timecreated   etc?
>
> @property
> def personaname(self):
> return self._personaname
>
Unless the formatting got screwed up in the email, all or these return
statements need to be indented
> @property
> def lastlogoff(self):
> return self._lastlogoff
>
> @property
> def profileurl(self):
> return self._profileurl
>
> @property
> def _avatar(self):
> return self._avatar
>
> @property
> def _timecreated(self):
> return self._timecreated
>
> @property
> def _loccountrycode(self):
> return self._loccountrycode
>
>
> def fetch_user(steamid):
> req =
> urllib.request.urlopen('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=B9F55D955257F1EDC9B6D217B94FCD20&steamids='
> + steamid)
> content = json.loads(req.read().decode('utf-8'))["response"]["players"][0]
> print("DEBUG ONLY: " + content["avatar"] + "\n")

try this:
print content
>
> return User(content["steamid"], content["personaname"],
> content["lastlogoff"], content["profileurl"], content["avatar"],
> content["timecreated"], content["loccountrycode"])
>
>
> main module:
>
> from user import User
>
> u = User.fetch_user("76561198067618735")
> print(u)
>
>
> console output:
>
> DEBUG ONLY:
> http://media.steampowered.com/steamcommunity/public/images/avatars/da/da259bfaef7fe7c2521de78433977a6c006217
> c5.jpg
>
> Traceback (most recent call last):
>   File ".\main.py", line 3, in 
> u = User.fetch_user("76561198067618735")
>   File "D:\Documents\HomeBroker\user.py", line 50, in fetch_user
> return User(content["steamid"], content["personaname"],
> content["lastlogoff"], content["profileurl"], content["avata
> r"], content["timecreated"], content["loccountrycode"])
>   File "D:\Documents\HomeBroker\user.py", line 11, in __init__
> self._avatar = avatar
> AttributeError: can't set attribute
>
>
> Why am I getting this "AttributeError: can't set attribute" specifically
> when trying to set 'self._avatar = avatar'?

Why not print out all of the content data.  Something around avatar
might look strange.
>
> Does my code in user.py module follows the pythonic way now?
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Joel Goldstick
http://joelgoldstick.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Juan Christian
So... I tried to follow all what you guys said:

user.py module:

import urllib.request
import json

class User():

def __init__(self, steamid, personaname, lastlogoff, profileurl, avatar,
timecreated, loccountrycode):
self._steamid = steamid
self._personaname = personaname
self._lastlogoff = lastlogoff
self._profileurl = profileurl
self._avatar = avatar
self._timecreated = timecreated
self._loccountrycode = loccountrycode


@property
def steamid(self):
return self._steamid

@property
def personaname(self):
return self._personaname

@property
def lastlogoff(self):
return self._lastlogoff

@property
def profileurl(self):
return self._profileurl

@property
def _avatar(self):
return self._avatar

@property
def _timecreated(self):
return self._timecreated

@property
def _loccountrycode(self):
return self._loccountrycode


def fetch_user(steamid):
req = urllib.request.urlopen('
http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=B9F55D955257F1EDC9B6D217B94FCD20&steamids='
+ steamid)
content = json.loads(req.read().decode('utf-8'))["response"]["players"][0]
print("DEBUG ONLY: " + content["avatar"] + "\n")

return User(content["steamid"], content["personaname"],
content["lastlogoff"], content["profileurl"], content["avatar"],
content["timecreated"], content["loccountrycode"])


main module:

from user import User

u = User.fetch_user("76561198067618735")
print(u)


console output:

DEBUG ONLY:
http://media.steampowered.com/steamcommunity/public/images/avatars/da/da259bfaef7fe7c2521de78433977a6c006217
c5.jpg

Traceback (most recent call last):
  File ".\main.py", line 3, in 
u = User.fetch_user("76561198067618735")
  File "D:\Documents\HomeBroker\user.py", line 50, in fetch_user
return User(content["steamid"], content["personaname"],
content["lastlogoff"], content["profileurl"], content["avata
r"], content["timecreated"], content["loccountrycode"])
  File "D:\Documents\HomeBroker\user.py", line 11, in __init__
self._avatar = avatar
AttributeError: can't set attribute


Why am I getting this "AttributeError: can't set attribute" specifically
when trying to set 'self._avatar = avatar'?

Does my code in user.py module follows the pythonic way now?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Steven D'Aprano
On Mon, Sep 08, 2014 at 04:01:01AM +1000, Steven D'Aprano wrote a bunch 
of stuff about the User class...


Ah, sorry guys, I did *not* intend to send that post. It's probably a 
bit incoherent, and certainly unfinished. I hit the wrong key and my 
mail program sent it.

If I get time to finish it tomorrow, I'll resend it. (But, alas, I 
probably won't. Sorry.)


-- 
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Steven D'Aprano
On Sun, Sep 07, 2014 at 12:00:15AM -0300, Juan Christian wrote:
> I'm writing a program that have a 'User' class. This class will have the
> following attributes:
> 
> 1. id
> 2. personaname
> 3. lastlogoff
> 4. profileurl
> 5. avatar
> 6. realname
> 7. timecreated
> 8. loccountrycode
> 
> I'm thinking about writing something like that: http://pastebin.com/7KHB2qQ8

For small code snippets, just include it in the body of your email. This 
is a small code snippet :-)


class User():
def __init__(id):
self.__id = id
[URL Request to call API and get everything using the ID (JSON)]
self.__personaname = [JSON response personaname]
self.__lastlogoff = [JSON response personaname]
[...]
def get_id():
return __id
def get_personaname():
return __personaname


> Is it a good approach, is this phytonic?

Nope, it's more like Java than Python. And it's buggy.

Here are some questions you should ask yourself:

- Are you likely to subclass User? If you do subclass, is it reasonable
  to treat the fields as part of the public API?

- Why are coupling the User class to the database? That makes it hard
  to separate the construction of a User (say, for testing) from
  database lookups.


This is my suggestion for a Pythonic approach, with some of the bugs 
fixed, and using more Pythonic naming conventions.


class User(object):
# Class attribute is shared by all instances.
_database = XXX  # reference to a database

def __init__(self, id, persona_name, last_logoff, profile_url, 
 avatar, real_name, time_created, loc_country_code):
# Data validation is left as an exercise.
self.id = id
self.persona_name = persona_name
self.last_logoff = last_logoff
# [etc. ...]

@classmethod
def fromid(cls, id):
args = cls._database.lookup_by_id(id)  # or some method
return cls(*args)


And that's pretty much it for the initial version. Some features:

- There is a class attribute (and therefore shared by all instances) 
  called _database. In the Java world, I think that would be called 
  a "static variable". The leading underscore makes it a private 
  attribute by convention. By making this an attribute rather than
  hard-coding it inside methods, it makes it easy to override during
  testing:

saved_database = User._database
User._database = Mock()
# continue as usual, with no further changes needed
# when you are done:
User._database = saved_database

- The initialiser method __init__ takes eight explicit arguments, plus
  "self". This enables you to create instances without reading them from
  the database, e.g. creating them on the fly, reading from an INI file, 
  or any other source. This is especially useful during testing.

  However, the downside of this is that you need to add argument 
  validation, since you can no longer assume the database has validated
  all the values. Or, you can just trust the caller knows what they are
  doing.

- There's an alternative constuctor offered, to support the case where 
  you do want to read the arguments from the database. So you can create
  Users two ways:

instance = User(1234, 'fred', ...)  # provide all the arguments

instance = User.fromid(1234)  # or via database lookup


We can extend this minimal version. Suppose you want writing to the 
attributes to update the database. We do this by making all the 
attributes computed properties, with an extra private method.

class User(object):
# Class attribute is shared by all instances.
_database = XXX  # reference to a database

# The init method stays the same.
def __init__(self, id, persona_name, last_logoff, profile_url, 
 avatar, real_name, time_created, loc_country_code):
# Data validation is left as an exercise.
self.id = id
self.persona_name = persona_name
self.last_logoff = last_logoff
# [etc. ...]

# But now we add a bunch of properties.

def _get_id(self):














[URL Request to call API and get everything using the ID (JSON)]
self.__personaname = [JSON response personaname]
self.__lastlogoff = [JSON response personaname]
[...]
def get_id():
return __id
def get_personaname():
return __personaname











> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Juan Christian
>
> > On Sun, Sep 7, 2014 at 5:04 AM, Peter Otten <__pete...@web.de> wrote:
>
> > I would call it with ID only and them the API server would return me
> > all the info, and then I would set them. I didn't learn '@classmethod'
> > decoration yet, but I presume it would work as a 'get()', right? The
> thing
> > is, where 'user with id 43' is stored? You get it using 'from_id' but we
> > don't have any list in there the store users, I got confused in that
> part.
>
> Maybe it becomes clearer with a small change. Instead of the classmethod
> you
> could use a normal function:
>
> class User:
> def __init__(self, id, personname, ...):
> self.id = id
> self.personname = personname
> ...
>
> def fetch_user_from_server(id):
> json_user = fetch data_from_server(id)
> return User(id, json_user["personname"], ...)
>
> jim = fetch_user_from_server(42)
>

I'll definitely use the '@property' decoration. Thanks for the tip, so, a
different module to accommodate all the API requests and one for the
logic/code itself is a better approach, right?



> If you should later decide that you want to provide a way to allow entering
> new users you could use the User class for that, too:
>
> def create_new_user():
> personname = input("Name: ") # in real code this would rather be a
>  # gui dialog or web page
> ...
> return User(None, personname, ...)
>
> new_guy = create_new_user()
> save_user_to_server(new_guy)
>
> You don't have to worry that the __init__() method tries to load data for
> an
> inexistent user.
>
> But even if you are sure you'll never do that it is still a good idea to
> keep concerns separate, if only to write independent unit tests for the
> User
> class and the server access.


Creating new users won't exist, my program is like a Home Broker using the
Steam API. This 'User' class will be mainly used to properly store the
users data, I'll automatically and recursively go trough my (or any person)
friend-list and fetch users info and inventory and properly use it in my
favor.

Here is an example of JSON response from the Steam API:

{
"response": {
"players": [
{
"steamid": "76561198067618735",
"communityvisibilitystate": 3,
"profilestate": 1,
"personaname": "wildee14",
"lastlogoff": 1410065399,
"commentpermission": 1,
"profileurl": 
"http://steamcommunity.com/id/wildee14/";,
"avatar": 
"http://media.steampowered.com/steamcommunity/public/images/avatars/da/da259bfaef7fe7c2521de78433977a6c006217c5.jpg";,
"avatarmedium":
"http://media.steampowered.com/steamcommunity/public/images/avatars/da/da259bfaef7fe7c2521de78433977a6c006217c5_medium.jpg";,
"avatarfull":
"http://media.steampowered.com/steamcommunity/public/images/avatars/da/da259bfaef7fe7c2521de78433977a6c006217c5_full.jpg";,
"personastate": 0,
"realname": "wildee",
"primaryclanid": "103582791429571843",
"timecreated": 1342807007,
"personastateflags": 0,
"loccountrycode": "US"
}
]

}
}
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Peter Otten
Juan Christian wrote:

> On Sun, Sep 7, 2014 at 5:04 AM, Peter Otten <__pete...@web.de> wrote:
>>
>> It's not a good approach and it's not pythonic.
>>
>> In Python you should avoid accessor functions and (pseudo-)private
>> __attributes ("Python is not Java"). So
>>
>> class User:
>> def __init__(self, id):
>> self.id = id
>> # load attributes
>> self.personname = [personname from JSON]
>> ...
>>
>> user = User(42)
>>
>> is certainly better. You might also consider making the class less
>> dependent
>> of the way you acquire the corresponding data:
>>
>> class User: # in Python 2: class User(object): ...
>> def __init__(self, id, personname, ...)
>> self.id = id
>> self.personname = personname
>> ...
>> @classmethod
>> def from_id(class_, id):
>> # load attributes
>> return User(id, personname, ...)
>>
>> jeff = User(42, "Jeff", ...)
>> jack = User.from_id(43)
> 
> 
> 
> Ok, no pseudo-private attributes. I read it in tutorials from 2013 and in
> the course that I'm taking that this would be a good pythonic way to deal
> with class attributes. They wouldn't be truly private, but someone using
> the program would see the " __ " in the beginning of the attribute and
> wouldn't call it directly, "because we are all adults and such", you
> saying that this approach doesn't exist in real life?

The double underscore plus name mangling is mainly to avoid name collisions 
in subclasses; to signal "this is private" a single underscore would 
suffice. But you then go on to make the attribute public via a a getter. In 
that case my first choice are normal attributes so that you can write

print(user.personname) # pythonic

instead of

print(user.get_personname()) # Javaism

If you want to prohibit the user from doing

user.personname = "Frankenstein" 

because the new name is not propagated to the database and the assignment 
puts your application into an inconsistent state which you want to avoid by 
some "bondage and discipline" you can change personname into a property:

class User:
def __init__(self, id):
...
self._personname = [as extracted from the JSON]

@property
def personname(self):
return self._personname


user = User(42)
print(user.personname) # implicitly calls the personname(self) method

> I can't give all the 8 attributes to '__init__' because I don't even have
> them. 

At least not now ;) My suggestion would decouple creation of the User 
instance and fetching of user-related data from a server.

> I would call it with ID only and them the API server would return me
> all the info, and then I would set them. I didn't learn '@classmethod'
> decoration yet, but I presume it would work as a 'get()', right? The thing
> is, where 'user with id 43' is stored? You get it using 'from_id' but we
> don't have any list in there the store users, I got confused in that part.

Maybe it becomes clearer with a small change. Instead of the classmethod you 
could use a normal function:

class User:
def __init__(self, id, personname, ...):
self.id = id
self.personname = personname
...

def fetch_user_from_server(id):
json_user = fetch data_from_server(id)
return User(id, json_user["personname"], ...)

jim = fetch_user_from_server(42)

If you should later decide that you want to provide a way to allow entering 
new users you could use the User class for that, too:

def create_new_user():
personname = input("Name: ") # in real code this would rather be a 
 # gui dialog or web page
...
return User(None, personname, ...)

new_guy = create_new_user()
save_user_to_server(new_guy)

You don't have to worry that the __init__() method tries to load data for an 
inexistent user. 

But even if you are sure you'll never do that it is still a good idea to 
keep concerns separate, if only to write independent unit tests for the User 
class and the server access.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Juan Christian
On Sun, Sep 7, 2014 at 5:04 AM, Peter Otten <__pete...@web.de> wrote:
>
> It's not a good approach and it's not pythonic.
>
> In Python you should avoid accessor functions and (pseudo-)private
> __attributes ("Python is not Java"). So
>
> class User:
> def __init__(self, id):
> self.id = id
> # load attributes
> self.personname = [personname from JSON]
> ...
>
> user = User(42)
>
> is certainly better. You might also consider making the class less
> dependent
> of the way you acquire the corresponding data:
>
> class User: # in Python 2: class User(object): ...
> def __init__(self, id, personname, ...)
> self.id = id
> self.personname = personname
> ...
> @classmethod
> def from_id(class_, id):
> # load attributes
> return User(id, personname, ...)
>
> jeff = User(42, "Jeff", ...)
> jack = User.from_id(43)



Ok, no pseudo-private attributes. I read it in tutorials from 2013 and in
the course that I'm taking that this would be a good pythonic way to deal
with class attributes. They wouldn't be truly private, but someone using
the program would see the " __ " in the beginning of the attribute and
wouldn't call it directly, "because we are all adults and such", you saying
that this approach doesn't exist in real life?

I can't give all the 8 attributes to '__init__' because I don't even have
them. I would call it with ID only and them the API server would return me
all the info, and then I would set them. I didn't learn '@classmethod'
decoration yet, but I presume it would work as a 'get()', right? The thing
is, where 'user with id 43' is stored? You get it using 'from_id' but we
don't have any list in there the store users, I got confused in that part.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Peter Otten
Juan Christian wrote:

> I'm writing a program that have a 'User' class. This class will have the
> following attributes:
> 
> 1. id
> 2. personaname
> 3. lastlogoff
> 4. profileurl
> 5. avatar
> 6. realname
> 7. timecreated
> 8. loccountrycode
> 
> I'm thinking about writing something like that:

> class User():
>  
> def __init__(id):
> self.__id = id
>
> [URL Request to call API and get everything using the ID (JSON)]
>  
> self.__personaname = [JSON response personaname]

> [...]
>  
> def get_id():
> return __id
>  
> def get_personaname():
> return __personaname
>  
> [...]

> Is it a good approach, is this phytonic?

It's not a good approach and it's not pythonic.

In Python you should avoid accessor functions and (pseudo-)private 
__attributes ("Python is not Java"). So

class User:
def __init__(self, id):
self.id = id
# load attributes
self.personname = [personname from JSON] 
... 

user = User(42)

is certainly better. You might also consider making the class less dependent 
of the way you acquire the corresponding data:

class User: # in Python 2: class User(object): ...
def __init__(self, id, personname, ...)
self.id = id
self.personname = personname
...
@classmethod
def from_id(class_, id):
# load attributes
return User(id, personname, ...)

jeff = User(42, "Jeff", ...)
jack = User.from_id(43)


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-07 Thread Alan Gauld

On 07/09/14 04:00, Juan Christian wrote:

I'm writing a program that have a 'User' class. This class will have the
following attributes:

1. id
2. personaname
3. lastlogoff
4. profileurl
5. avatar
6. realname
7. timecreated
8. loccountrycode

I'm thinking about writing something like that: http://pastebin.com/7KHB2qQ8



When its a short bit of code (<100 lines) just put it in
the email body...

class User():

def __init__(id):
self.__id = id

[URL Request to call API and get everything using the ID (JSON)]

self.__personaname = [JSON response personaname]
self.__lastlogoff = [JSON response personaname]
[...]

This is fine although the question of whether you need the attributes to 
be private needs to be considered carefully on a per attribute basis.


def get_id():
return __id

def get_personaname():
return __personaname

But this style is not Pythonic. If you have a method that
just returns the attribute its better to just make the attribute
non-private and allow users to access it directly.

In fact even if you wanted to do some processing around
the access, rather than have lots of getXXX methods it
would be more Pythonic to write get/set methods but then
declare the attribute as a property and hide the get/set
methods so that, to the user, it looks like direct access.
get/set methods are a very Java-ish kind of style but
not really Pythonic. For most cases direct access is
preferred.

Also, as a matter of style/convention, the class name is
usually CamelCased so it would be

class User:

Similarly  attribute names are usually spaced using
underscores so personaname becomes persona_name etc.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Good approach regarding classes attributes

2014-09-06 Thread Juan Christian
Ops, sorry.

Pastebin @ line 9: It's [JSON response lastlogoff]


On Sun, Sep 7, 2014 at 12:00 AM, Juan Christian 
wrote:

> I'm writing a program that have a 'User' class. This class will have the
> following attributes:
>
> 1. id
> 2. personaname
> 3. lastlogoff
> 4. profileurl
> 5. avatar
> 6. realname
> 7. timecreated
> 8. loccountrycode
>
> I'm thinking about writing something like that:
> http://pastebin.com/7KHB2qQ8
>
> Is it a good approach, is this phytonic?
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Good approach regarding classes attributes

2014-09-06 Thread Juan Christian
I'm writing a program that have a 'User' class. This class will have the
following attributes:

1. id
2. personaname
3. lastlogoff
4. profileurl
5. avatar
6. realname
7. timecreated
8. loccountrycode

I'm thinking about writing something like that: http://pastebin.com/7KHB2qQ8

Is it a good approach, is this phytonic?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor