0

Suppose a "person" class contains name, age and phone number.

When creating a person object, I would like to set phone number by looking up an external phone book rather than explicitly passing a phone number.

Option 1: Store phone book as a class variable

class person():

    phonebook = {}

    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.phone = self.phonebook[self.name]

person.phonebook = {'dan':1234}
dan = person('dan', 30)

Option 2: Create a class object without phone number then have a separate function to load it.

class person():

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def loadphone(self, phone):
        self.phone = phone

phonebook = {'dan':1234}
dan = person('dan',30)
dan.loadphone(phonebook['dan'])

Both solutions do not seem optimal. Option 1, every person carries a phone book (unnecessarily). Option 2 requires 2-step initialization.

Is there a better way to create a person object without 1) explicitly passing a phone number or phone book during initialization, 2) storing phone book as a class variable, and 3) requiring a multi-step initialization?

5
  • 2
    Option 1 would have everyone carrying the same phonebook in python. Commented Jul 20, 2017 at 17:37
  • 4
    "Option 1, every person carries a phone book (unnecessarily)" This is not true, every instance has access to a single phone book which is stored as data on the class (and lookup on an instance will check the class dictionary if not found on the instance). Commented Jul 20, 2017 at 17:37
  • 2
    "every person carries a phone book (unnecessarily)" - Incorrect. Every person has accesses to the phone-book, but not every person carries a phone-book. The class object is what stores the phone-book. Commented Jul 20, 2017 at 17:37
  • In option 1, there's no self.phonebook. Commented Jul 20, 2017 at 17:37
  • 1
    In option 1, the phonebook belongs to the class. The instances of a class have access to it's namespace, though. Commented Jul 20, 2017 at 17:37

3 Answers 3

3

As discussed in this post, defining a variable outside of any methods in the class, while still being defined in a class makes it a static variable, such as the one you have:

class person():

    phonebook = {}

This means that there is a single phonebook which all instances of the class refer to

person.phonebook{'dave':1234, 'joey':5678}

dave = person('dave', 30)
joey = person('joey', 23)

There is still only the one universal phonebook that all instances refer to. The one thing to change in that code is that you should not define it as self.phonebook['dave'] so it should look like

class person():

    phonebook = {}

    def __init__(name, age):
        self.name = name
        self.age = age
        self.number = phonebook[name]
Sign up to request clarification or add additional context in comments.

Comments

1

Are you wanting to optionally define a phone number for a Person? You could do something like below:

class Person():
    def __init__(self, name, age, phone=None):
        self.name = name
        self.age = age
        self.phone = phone

dan = Person('dan',30, phone=1234)
stan = Person('stan', 60)

Comments

0

Firstly, as for me, it's too wide question and very depend on task. In one case you can access to PhoneBook, in another - it's bad idea (e.g. PhoneBook load data from server and creating 1000 of Person will produce 1000 requests).

Secondary, their is next approach:

class BasicPerson():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def ToString(self):
        return('some code')

class PersonWithPhone():
    def __init__(self, basicPerson, phone):
        self.basicPerson = basicPerson
        self.phone = phone

    def ToString(self):
        return('another code ' + self.basicPerson.ToString())

person = PersonWithPhone(BasicPerson('', ''), '11111')

It's just example and may seems useless, but in many situations you can extract some core actions (ToString, for example) and than wrote small decorators that expand each other.

2 Comments

Why not just make PersonWithPhone a child class and use the super method.
Because you can easily pass some PersonWithHomeAddress(WithMobile(WithTwitter())) and than wrap it into DBStoredPerson. Inheritance are provide same result only in simple cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.