Python 如何最好地从方法创建对象变量

Python 如何最好地从方法创建对象变量,python,class,oop,object,design-patterns,Python,Class,Oop,Object,Design Patterns,设置由方法设置的对象变量的最佳方法是什么?在下面的方法中,首先在中定义self.toppings,然后在select\u toppings()方法中设置值,这是否是设置self.toppings变量的良好实践?如果你有更好的建议,请告诉我。谢谢 class Pizza: def __init__(): self.toppings = None def select_toppings(input): self.toppings = input

设置由方法设置的对象变量的最佳方法是什么?在下面的方法中,首先在
中定义
self.toppings
,然后在
select\u toppings()
方法中设置值,这是否是设置
self.toppings
变量的良好实践?如果你有更好的建议,请告诉我。谢谢

class Pizza:

    def __init__():
        self.toppings = None 

    def select_toppings(input):
        self.toppings = input  

您可以将
浇头直接传递给构造函数。(不要用作变量名,因为它是python内置函数)


输出将是
奶酪

您可以将
配料
直接传递给构造器。(不要用作变量名,因为它是python内置函数)


输出将是
cheese

这里是使用
属性设置的另一种方法

class Pizza:
    def __init__(self):
        self._toppings = None

    def get_toppings(self):
        print("get_toppings called!")
        return self._toppings

    def set_toppings(self, x):
        print("set_toppings called!")
        self._toppings = x

    toppings = property(get_toppings, set_toppings)

margherita = Pizza()
margherita.set_toppings("mozzarella cheese")
print(margherita.get_toppings())

# outputs 
mozzarella cheese
没有
set
get
方法的一个陷阱是,我希望您能看到它是如何导致变量更改问题的

class Pizza:

    def __init__(self, toppings, dough):
        self.toppings = toppings
        self.pizza = toppings + ', ' + dough

pz = Pizza('cheese', 'flour')
pz.toppings = "chicken"
print(pz.toppings)
print(pz.pizza)

# outputs 
chicken
cheese, flour

下面是使用
属性设置的另一种方法

class Pizza:
    def __init__(self):
        self._toppings = None

    def get_toppings(self):
        print("get_toppings called!")
        return self._toppings

    def set_toppings(self, x):
        print("set_toppings called!")
        self._toppings = x

    toppings = property(get_toppings, set_toppings)

margherita = Pizza()
margherita.set_toppings("mozzarella cheese")
print(margherita.get_toppings())

# outputs 
mozzarella cheese
没有
set
get
方法的一个陷阱是,我希望您能看到它是如何导致变量更改问题的

class Pizza:

    def __init__(self, toppings, dough):
        self.toppings = toppings
        self.pizza = toppings + ', ' + dough

pz = Pizza('cheese', 'flour')
pz.toppings = "chicken"
print(pz.toppings)
print(pz.pizza)

# outputs 
chicken
cheese, flour

主要的问题是:当一个诚实的程序员写:

pizza = Pizza()
pizza.do_something()
dou_something()
需要
self.toppings!=无

记住:构造函数的作用是正确初始化对象。所有必填字段应在构造结束时初始化

如果对象的初始化变得太复杂(我会说:只要构造函数不仅仅是给字段赋值),就使用一个。以工厂为例:

class Pizza:
    @staticmethod
    def create(topping_list):
        toppings = Toppings(topping_list)
        return Pizza(toppings)

    def __init__(self, toppings):
        self._toppings = toppings

    ...
或建筑商:

class PizzaBuilder:
    def __init__(self):
        self._toppings = DEFAULT_TOPPINGS
        self._size = DEFAULT_SIZE

    def build(self):
        return Pizza(self.toppings, self._size)

    def toppings(self, toppings):
        self._toppings = toppings
        return self

    def size(self, size):
        self._size = size
        return self

class Pizza:
    def __init__(self, toppings, size):
        self._toppings = toppings
        self._size = size
您可以创建所需的所有组合:

pizza1 = PizzaBuilder().build() # default pizza
pizza2 = PizzaBuilder().size(10).build() # big pizza with default toppings
pizza3 = PizzaBuilder().toppings(t1).build() # ...

创造性模式的一个优点是对象完全初始化,并且在大多数情况下是不可变的。简单地说,setter和getter是分开的,程序的设计变得更干净。

主要的问题是:当一个诚实的程序员写:

pizza = Pizza()
pizza.do_something()
dou_something()
需要
self.toppings!=无

记住:构造函数的作用是正确初始化对象。所有必填字段应在构造结束时初始化

如果对象的初始化变得太复杂(我会说:只要构造函数不仅仅是给字段赋值),就使用一个。以工厂为例:

class Pizza:
    @staticmethod
    def create(topping_list):
        toppings = Toppings(topping_list)
        return Pizza(toppings)

    def __init__(self, toppings):
        self._toppings = toppings

    ...
或建筑商:

class PizzaBuilder:
    def __init__(self):
        self._toppings = DEFAULT_TOPPINGS
        self._size = DEFAULT_SIZE

    def build(self):
        return Pizza(self.toppings, self._size)

    def toppings(self, toppings):
        self._toppings = toppings
        return self

    def size(self, size):
        self._size = size
        return self

class Pizza:
    def __init__(self, toppings, size):
        self._toppings = toppings
        self._size = size
您可以创建所需的所有组合:

pizza1 = PizzaBuilder().build() # default pizza
pizza2 = PizzaBuilder().size(10).build() # big pizza with default toppings
pizza3 = PizzaBuilder().toppings(t1).build() # ...

创造性模式的一个优点是对象完全初始化,并且在大多数情况下是不可变的。简单地说,setter和getter是分开的,程序的设计更简洁。

这个原则适用于更大的类吗?它不是要在_init__()上做很多工作吗?谢谢。
\uuuu init\uuuu
就是为了这个。您可以在
\uuuu init\uuuu
中传递您想要实例化类的默认参数,然后在其他实例方法中使用它们(除非您的用例不同)。这个原则适用于更大的类吗?它不是要在_init__()上做很多工作吗?谢谢。
\uuuu init\uuuu
就是为了这个。您可以在
\uuuu init\uuuu
中传递您想要实例化类的默认参数,然后在其他实例方法中使用它们(除非您的用例不同?)也有
getter
setter
方法,您可以查看您的代码,这是一个很好的实践。它将允许阅读您的代码的开发人员只通过查看构造函数就知道存在哪些实例属性。另一方面,Python中很少有只设置属性的方法。也有
getter
setter
方法,您可以查看您的代码,这是很好的实践。它将允许阅读您的代码的开发人员只通过查看构造函数就知道存在哪些实例属性。另一方面,在Python中很少有只设置属性的方法。谢谢你的提示,有道理。谢谢你的提示。嗨,这是一个很好的方式来区分建筑商和比萨饼类。但是,我很难理解如何链接
PizzaBuilder()
Pizza()
?它们应该在同一个模块中。隐式链接是
PizzaBuilder.build
返回一个
Pizza
。如果需要,可以将
@staticmethod def builder():return PizzaBuilder()
添加到
Pizza
类中。第二个例子是:
Pizza.builder().size(10.build()
。您好,这是一个很好的分离builder和Pizza类的方法。但是,我很难理解如何链接
PizzaBuilder()
Pizza()
?它们应该在同一个模块中。隐式链接是
PizzaBuilder.build
返回一个
Pizza
。如果需要,可以将
@staticmethod def builder():return PizzaBuilder()
添加到
Pizza
类中。第二个例子是:
Pizza.builder().size(10.build()