Reputation: 8045
assign set of variables to class object,usually is this:
player.x = 1
player.y = 10
player.name = 'John'
since list and tuple allow you doing this
a,b,c = (1,10,'John')
so this works
player.x,player.y,player.name = (1,10,'John')
or this
player.x,player.y,player.name = 1,10,'John'
I would like to change player
properties, I need to type too much player
. Is the a more lazy way to do this?
Upvotes: 0
Views: 151
Reputation: 142126
I'm not 100% sure, but it sounds to me that in this instance, using a namedtuple
would be a better approach: the caveat being that only known fields should be present (ie, can't be dynamically added/removed) and the class isn't really anything more than a record with attribute style access to fields.
from collections import namedtuple
Player = namedtuple('Player', 'x y name')
player = Player._make([1, 3, 'Bob'])
print player
# Player(x=1, y=3, name='Bob')
player = player._replace(name='Jim', x=13)
print player
# Player(x=13, y=3, name='Jim')
Otherwise, I would personally go for the adding a convenience method to your Player class
.
Upvotes: 0
Reputation: 20339
A basic loop could work:
for (k,v) in zip(attribute_names, attributes_values):
setattr(player, k, v)
Of course, you could sue some list comprehension, like:
trash = [setattr(player, k, v) for (k,v) in zip(attribute_names, attributes_values)]
but it doesn't really improve anything (your trash
holds as many None
as len(attribute_names)
...
Upvotes: 1
Reputation: 50985
Here's another way of doing this, but like all the others, it's less readable than what you started with:
from functools import partial
map(partial(setattr, player), ("x", "y", "name"), (1, 10, 'John'))
If you set the same set or sets of attributes several places in your code, perhaps adding a well-named method for each such set is a better option?
class Player(object):
# [...]
def set_stats(self, x, y, name):
self.x = x
self.y = y
self.name = name
Then you can set these attributes using code that is both short and very readable:
player.set_stats(1, 10, "John")
Upvotes: 1
Reputation: 23545
What about something like this:
def set_properties(instance, properties):
for property in properties:
setattr(instance, property, properties[property])
Since we are talking about a lazy programmer you could rewrite the function as:
def set_properties(instance, properties):
for key,val in properties.iteritems():
setattr(instance, key, val)
The above code is a bit shorter, but should also run faster for large dictionaries, because it is unpacked once before the loop. Compare to the first version where there properties dictionary is called every iteration.
Usage:
set_properties(player, {'x': 1, 'y': 10, 'name': 'John'})
Upvotes: 2
Reputation: 250891
using zip()
and player.__dict__
:
In [14]: class player:
....: pass
....:
In [15]: for prop,value in zip(("x","y","name"),(1,10,"john")):
player.__dict__[prop]=value
....:
....:
In [18]: player.__dict__
Out[18]: {'__doc__': None, '__module__': '__main__', 'name': 'john', 'x': 1, 'y': 10}
Upvotes: 1
Reputation: 2558
player.__dict__.update({'x':12,'y':24,'name':'Billy'})
Not shorter but using dictionaries can be handy in more instances than just a direct example like you provided.
Upvotes: 2
Reputation: 9568
You could use a method to wrap together changes to properties you might find always happen together like def edit(self, **kwargs)
or just positional args and assign self.property = kwargs.get(propertyName, default)
on the player class within this. You can also create a property on the class that does the tuple assignment of the kind you have used in the example.
Upvotes: 0