0

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?

4
  • What's wrong with the first one? What are you trying to do? Commented Sep 14, 2012 at 7:24
  • 1
    Actually, in both cases, you will type "player" three times. In the second solution, you type more characters, as you need to type the parentheses and comma's to create a tuple. Commented Sep 14, 2012 at 7:27
  • 1
    I got it, you wanna do something like: with player: x = 1 y = 10 name = 'John' right? I believe there's no such opportunity. Commented Sep 14, 2012 at 7:36
  • 3
    The given code is perfectly fine, explicit and readable which is more important than having to type some letters more... Commented Sep 14, 2012 at 7:52

7 Answers 7

2

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'})
Sign up to request clarification or add additional context in comments.

Comments

2
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.

Comments

1

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}

Comments

1

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")

Comments

1

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)...

Comments

0

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.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.