使用外部数据初始化Python类对象

时间:2017-07-20 17:34:40

标签: python oop

假设“人”类包含姓名,年龄和电话号码。

创建人物对象时,我想通过查找外部电话簿而不是明确传递电话号码来设置电话号码。

选项1:将电话簿存储为类变量

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)

选项2:创建一个没有电话号码的类对象,然后有一个单独的函数来加载它。

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'])

两种解决方案似乎都不是最佳选择。选项1,每个人都携带电话簿(不必要)。选项2需要两步初始化。

有没有更好的方法来创建人物对象而没有1)在初始化期间明确传递电话号码或电话簿,2)将电话簿存储为类变量,以及3)需要多步骤初始化?

3 个答案:

答案 0 :(得分:3)

正如this帖子中所讨论的,在类中任何方法之外定义变量,同时仍在类中定义,使其成为静态变量,例如你拥有的那个:

class person():

    phonebook = {}

这意味着只有一个phonebook,该类的所有实例都引用

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

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

所有实例仍然只有一个通用phonebook。在该代码中要改变的一件事是你不应该将它定义为self.phonebook['dave']所以它应该看起来像

class person():

    phonebook = {}

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

答案 1 :(得分:1)

您是否要为Person选择定义电话号码?您可以执行以下操作:

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)

答案 2 :(得分:0)

首先,对我来说,问题太广泛,非常依赖于任务。在一种情况下,你可以访问PhoneBook,在另一种情况下 - 这是一个坏主意(例如,PhoneBook从服务器加载数据并创建1000 Person将产生1000个请求。)

中学,他们的下一步是:

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

这只是一个例子而且似乎没用,但在许多情况下,你可以提取一些核心动作(例如ToString),然后编写相互扩展的小装饰器。