2

I have an excel file that contains some required parameters and their values and I am trying to feed them into the __init__ function of my class entity. I know the below must be setting self.key to each value in turn, but should I be "masking"(?) the .key?:

class Customer:
    def __init__(self):
        for key, value in zip(excelDF.attribs, excelDF.values):
            if key!=None and value !=None:
                self.key= value

To give an example of what I am trying for:

excelDF.attribs=['name','telephone']
excelDF.values=['Tom','01234-567890']
customer1=Customer()
print(customer1.name)
print(customer1.telephone)

gives...

Tom
01234-567890
2
  • 1
    Use setattr() Commented May 30, 2017 at 10:50
  • 2
    @deepspace answer below is great, small remark for this code: don't use = and != for singleton objects like None, use is if you need such check for some reason Commented May 30, 2017 at 10:54

3 Answers 3

7

You should be using setattr:

class Customer:
    def __init__(self):
        for key, value in zip(excelDF.attribs, excelDF.values):
            if key is not None and value is not None:
                setattr(self, key, value)

If a key happens to be an invalid Python identifier it will only be accessible with getattr.

Usage example:

keys = ['a', 'b', 'c']
values = [1, 2, 3]

class Customer:
    def __init__(self):
        for key, value in zip(keys, values):
            if key is not None and value is not None:
                setattr(self, key, value)

cust = Customer()
print(cust.a, cust.b, cust.c)
# 1 2 3
Sign up to request clarification or add additional context in comments.

Comments

1

Another less conventional approach using type to define the class:

Customer = type("Customer",
                (),
                dict(zip(excelDF.attribs, excelDF.values)))

ref: http://python-course.eu/python3_classes_and_type.php

1 Comment

Correct, but this will get very messy if OP wants to define some methods in Customer class.
0

I want to present 2 alternatives:

#!/usr/bin/env python3


class Customer:
    def __init__(self, **kwargs):
        self.name = kwargs.get("name")
        self.number = kwargs.get("number")


class Customer2:
    name = ""
    number = ""

    @classmethod
    def from_dict(cls, d):
        o = cls()
        for k in [k for k in vars(cls) if not k.startswith("_")]:
            setattr(o, k, d.get(k))
        return o


keys = ["name", "number", "bla"]
values = ["John", "00109563221", "Blub"]

data = {k: v for k, v in zip(keys, values)}
c1 = Customer(**data)
c2 = Customer2.from_dict(data)

print(c1.name)
print(c2.number)

Here the stress lies on the constructor pulling in what it needs of the data instead of taking all that comes along.

Cave: Solution2 relies on the fact, that you only want dumb data objects, where the only fields you are interested in are defined class variables.

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.