Olivier Pons
Olivier Pons

Reputation: 15778

Python: how to use some kind of generic setter?

I've made this code:

if fc.get('field_photo_1'):
    pt.photo1 = fc.get('field_photo_1')
if fc.get('field_photo_2'):
    pt.photo2 = fc.get('field_photo_2')
if fc.get('field_photo_3'):
    pt.photo3 = fc.get('field_photo_3')

I'd like to optimize it to some kind of code like this:

update_field(photo1, 'field_photo_1'):
update_field(photo2, 'field_photo_2'):
update_field(photo3, 'field_photo_3'):

I just don't know how make kinddof a setter with index in python. How would you implement the update_field() function?

Upvotes: 0

Views: 123

Answers (5)

pzelasko
pzelasko

Reputation: 2322

You could use a dict:

photos = dict()
photos['photo1'] = fc.get('field_photo_1')
# etc...

Or more concisely:

photos = {photo: fc.get(photo) for photo in ('field_photo_1', 'field_photo_2', 'field_photo_3')}

Upvotes: 0

noctrnal
noctrnal

Reputation: 191

If you are wanting to set the pt attribute based on the passed parameter, setattr is the way to go.

def update_field(attribute, value):
    setattr(pt, attribute, value)

The other answers here assume that you are iterating through a preset number of photo attributes. If you are wanting a single set, then the above should work. If looking to set them all, Ben's or Ritave's answer might be more suitable.

Depending on the scope of the "pt" variable. You might have to do something like setattr(self.pt, attribute, value).

Upvotes: 0

Artur Padalianchyk
Artur Padalianchyk

Reputation: 304

You could take a look at the setattr() function.

Upvotes: 1

Ben
Ben

Reputation: 2472

You are looking for setattr, which accepts string attribute names.

Try this:

for x in range(1, 4):
    attrname = "photo_".format(x)
    setattr(pt, attrname, fc["field_".format(attrname)])

You should probably refactor your code though to use lists.

Upvotes: 0

Ritave
Ritave

Reputation: 1373

I would suggest making an array of photos and then iterate strings with a for loop instead of trying to create such setter. It's easier to understand and doesn't do uncommon things with your class that other programmers might not expect.

class Pt:
    def __init__(self):
        self.photos = [None for i in range(3)]

pt = Pt()
for i in range(1,4)
    fieldString = 'field_photo_{0}'.format(i)
    if fc.get(fieldString):
        pt.photos[i] = fc.get(fieldString)

Upvotes: 0

Related Questions