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

使用外部数据初始化Python类对象,python,oop,Python,Oop,假设“person”类包含姓名、年龄和电话号码 创建person对象时,我希望通过查找外部电话簿来设置电话号码,而不是显式地传递电话号码 选项1:将电话簿存储为类变量 class person(): phonebook = {} def __init__(self, name, age): self.name = name self.age = age self.phone = self.phonebook[self.name]

假设“person”类包含姓名、年龄和电话号码

创建person对象时,我希望通过查找外部电话簿来设置电话号码,而不是显式地传递电话号码

选项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需要两步初始化


有没有更好的方法来创建person对象,而无需1)在初始化过程中显式传递电话号码或电话簿,2)将电话簿存储为类变量,以及3)需要多步骤初始化?

是否希望为
人员定义电话号码?您可以执行以下操作:

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)

您是否希望有选择地为
人员定义电话号码
?您可以执行以下操作:

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)
如后文所述,在类中的任何方法之外定义变量,而仍然在类中定义变量,使其成为静态变量,例如:

class person():

    phonebook = {}
这意味着该类的所有实例都引用一个电话簿

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

dave = person('dave', 30)
joey = person('joey', 23)
仍然只有一个通用的
电话簿
,所有实例都引用它。代码中需要更改的一点是,您不应该将其定义为
self.phonebook['dave']
,因此它应该是

class person():

    phonebook = {}

    def __init__(name, age):
        self.name = name
        self.age = age
        self.number = phonebook[name]
如后文所述,在类中的任何方法之外定义变量,而仍然在类中定义变量,使其成为静态变量,例如:

class person():

    phonebook = {}
这意味着该类的所有实例都引用一个电话簿

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

dave = person('dave', 30)
joey = person('joey', 23)
仍然只有一个通用的
电话簿
,所有实例都引用它。代码中需要更改的一点是,您不应该将其定义为
self.phonebook['dave']
,因此它应该是

class person():

    phonebook = {}

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

首先,对我来说,这是一个太宽泛的问题,非常依赖于任务。在一种情况下,您可以访问电话簿;在另一种情况下,这是一个坏主意(例如,电话簿从服务器加载数据,并创建1000个
将产生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),然后编写相互扩展的小装饰程序。

首先,对我来说,这是一个太宽泛的问题,非常依赖于任务。在一种情况下,您可以访问电话簿;在另一种情况下,这是一个坏主意(例如,电话簿从服务器加载数据,并创建1000个
将产生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
),然后编写相互扩展的小装饰程序。

选项1会让每个人都携带python中的同一个电话簿。“选项1,每个人都携带一个电话簿(不必要地)”这不是真的,每个实例都可以访问一个电话簿,该电话簿作为类上的数据存储(如果在实例上找不到,则查找实例将检查类字典)。“每个人都携带一个电话簿(不必要)”-不正确。每个人都可以访问电话簿,但不是每个人都有电话簿。class对象是存储电话簿的对象。在选项1中,没有
self.phonebook
。在选项1中,电话簿属于该类。不过,类的实例可以访问其名称空间。选项1会让每个人都携带python中相同的电话簿。“选项1,每个人都携带一个电话簿(不必要)“这不是真的,每个实例都可以访问作为类上数据存储的单个电话簿。”(如果在实例上找不到,则在实例上查找将检查类词典)。“每个人都携带一本电话簿(不必要地)”-不正确。每个人都可以访问电话簿,但不是每个人都有电话簿。类对象是存储电话簿的对象。在选项1中,没有
self.phonebook
。在选项1中,电话簿属于该类。不过,类的实例可以访问其命名空间。为什么不直接将
PersonWithPh设置为一个
是一个子类,使用super方法。因为你可以很容易地通过HomeAddress(WithMobile(WithTwitter())传递一些
然后将其包装到
DBStoredPerson
中。继承仅在简单的情况下提供相同的结果。为什么不将
PersonWithPhone
作为子类并使用super方法。因为您可以轻松地传递一些
PersonWithHomeAddress(WithMobile(WithTwitter()))
然后将其包装到
DBStoredPerson
中。继承仅在简单的情况下提供相同的结果。