Python - 类与对象 - 书中实例0601

说明

  • 定义实例属性: __init __( ) :英文单词 initialization ,初始化;
  • 实例方法(self)

实例来源与说明

  • 《Python编程入门经典》- 第6章节 书中案例
  • 关键词: fridge 、omelet
  • 已经调试出正确结果

代码区域

#!/usr/bin/env python3.1

class Fridge:  
    """This class implements a fridge where ingredients can be added and removed individually,or in group.
    The fridge will retain  count of every inqredient added or removed,and will raise raise an error if a sufficient quantity of an ingredient isn't present.
    Methods:
    has(food_name [,quantity]) - checks if the string food_name is in the fridge.Quantity will be set to 1 if you dont't specify a number.
    has_various(foods) - checks if enough og every food in the dictionary is in the fridge
    add_one(food_name) - adda a single food_name to the fridge
    add_many(food_dict) - adds a whole dictionary filled with food
    get_one(food_name) - takes out a single food_name from the fridge
    get_many(food_dict) - takes out a whole dictionary worth of food.
    get_ingredients(food) - If passes an object that has the__ingredients__method,get_many will invoke this to get the laist of ingredients.
    """
    def __init__(self, items={}):  # 声明需要与外部交互的参数
        """Optionally pass in an initial dictionary of items"""
        if type(items) != type({}):
                 raise TypeError("Fridge requires a dictionary but was given %s" % type(items))
        self.items = items
        return

    def __add_multi(self,food_name,quantity):  #类的方法 1:增加食物
        """__add_multi(food_name,quantity) - adds more than one if a food item. Returns the number of items added.
        This should only be used internally, after the type checking has been done
        """
        if (not food_name in self.items):
            self.items[food_name] = 0
        self.items[food_name] = self.items[food_name] + quantity

    def add_one(self, food_name): 
        """
        add_one(food_name) - adds a single food_name to the fridge returns True
        Raises a TypeError if food_name is not a string.
        """
        if type(food_name) != type(""):
            raise TypeError("add_one requires a string, given a %s" % type(food_name))
        else:
            self.__add_multi(food_name, 1)
        return True

    def add_many(self, food_dict):
        """
        add_many(food_dict) - adds a whole dictionary filled with food as keys and quantities as values.
        returns a dictionary with the removed food.
        raises a TypeError if food_dict is not a dictionary returns False if there is not enough food in the fridge.
        """
        if type(food_dict) != type({}):
            raise TypeError("add_many requires a dictionary,got a %s" % food_dict)
        for item in food_dict.keys():
            self.__add_multi(item, food_dict[item])
        return

    def has(self, food_name, quantity=1):  
        """
        has(food_name,[quantity]) - checks if the string food_name is in the fridge. Quantity defaults to 1
        Return True if there is enough, False otherwise.
        """
        return self.has_various({food_name: quantity})

    def has_various(self, foods):
            """
            has_various(foods) determines if the dictionary food_name    has enough of every element to satisfy a request.
            returns True if there's enough, Flase if there's not or if an element does not exist.
            """
            try:
                for food in foods.keys():
                    if self.items[food] < foods[food]:
                        return False
                return True
            except KeyError:
                return False

    def __get_multi(self, food_name, quantity):
        """
        returns False if there isn't enough food_name in the fridge.
        This should only be used internally,after the type checking has been done
        """
        try:
            if (self.items[food_name] is None):
                return False;

            if (quantity > self.items[food_name]):
                 return False;
            self.items[food_name] = self.items[food_name] - quantity
        except KeyError:
            return False
        return quantity

    def get_one(self, food_name):
        """
        get_one(food_name) - takes out a single food_name from the fridge
        returns a dictionary with the food:1 as a result, or False if there wasn't enough in the fridge.
        """
        if type(food_name) != type(""):
            raise TypeError("get_one requires a string,given a %s" % type(food_name))
        else:
            result = self.__get_multi(food_name, 1)
        return result

    def get_many(self, food_dict):
        """
        get_many(food_dict) - takes out a whole dictionary worth of food.
        returns a dictionary with all of the ingredients
        returns False if there are not enough ingredients or if a dictionary isn't provided.
        """
        if self.has_various(food_dict):
            foods_removed = {}
            for item in food_dict.keys():
                foods_removed[item] = self.__get_multi(item, food_dict[item])
            return foods_removed

    def get_ingredients(self, food):
        """
        get_ingredients(food) - If passes an object that the __ingredients_method,get_many will invoke this to get the list of ingredients.
        """
        try:
            ingredients = self.get_many(food.__ingredients__())
        except AttributeError:
            return False
        if ingredients != False:
            return ingredients


class Omelet:
    """This class creates an omelet object. An omelet can be in one of two states: ingredients,or cooked.
    An omelet object has the following interfaces:
    get_kind() - returns a string with the type of omelet
    set_kind(kind) - sets the omelet to be type named
    set_new_kind(kind, ingredients) - lets you create an omelet
    mix() - gets called after all the ingredients are gathered from the firdge
    make() - cooks the omelet
    """
    def __init__(self, kind="cheese"):
        """__init__(self, kind="cheese")
        This initializes the Omelet class to default to be a cheese omelet.
        Other methods
        """
        self.set_kind(kind)
        return

    def __ingredients__(self):
        """Internal method to be called on by a fridge or other objects that need to act on ingredients."""
        return self.needed_ingredients

    def get_kind(self): 
        return self.kind

    def set_kind(self, kind): 
        possible_ingredients = self.__known_kinds(kind)
        if possible_ingredients == False:
            return False
        else:
            self.kind = kind
            self.needed_ingredients = possible_ingredients

    def set_new_kind(self, name, ingredients): 
        self.kind = name
        self.needed_ingredients = ingredients
        return

    def __known_kinds(self, kind):
        if kind == "cheese":
            return {"eggs":2, "milk":1, "cheese":1}
        elif kind == "mushroom":
            return {"eggs":2, "milk":1, "cheese":1, "mushroom":2}
        elif kind == "onion":
            return {"eggs":2, "milk":1, "cheese":1, "onion":1}
        else:
            return False

    def get_ingredients(self, fridge):
        self.from_fridge = fridge.get_ingredients(self)

    def mix(self): 
        for ingredient in self.from_fridge.keys():
            print("Mixing %d %s for the %s omelet" % (self.from_fridge[ingredient], ingredient, self.kind))
        self.mixed = True

    def make(self):
        if self.mixed == True:
            print("Cooking the %s omelet!" % self.kind)
            self.cooked = True

调试区

用 python -i 命令加载,得出如下结果

H:\LearningPython>python -i ch0601.py
>>> o = Omelet("cheese")
>>> f = Fridge({"cheese":5,"milk":4, "eggs":12})
>>> o.get_ingredients(f)
>>> o.mix()
Mixing 2 eggs for the cheese omelet
Mixing 1 milk for the cheese omelet
Mixing 1 cheese for the cheese omelet
>>> o.make()
Cooking the cheese omelet!
>>>
>>> f = Fridge({"cheese":5, "milk":4, "eggs":12, "mushroom":6, "onion":6})
>>> o = Omelet("cheese")
>>> m = Omelet("mushroom")
>>> c = Omelet("onion")
>>> o.get_ingredients(f)
>>> o.mix()
Mixing 2 eggs for the cheese omelet
Mixing 1 milk for the cheese omelet
Mixing 1 cheese for the cheese omelet
>>> m.get_ingredients(f)
>>> m.mix()
Mixing 2 eggs for the mushroom omelet
Mixing 1 milk for the mushroom omelet
Mixing 1 cheese for the mushroom omelet
Mixing 2 mushroom for the mushroom omelet
>>> c.get_ingredients(f)
>>> c.mix()
Mixing 2 eggs for the onion omelet
Mixing 1 milk for the onion omelet
Mixing 1 cheese for the onion omelet
Mixing 1 onion for the onion omelet
>>> o.make()
Cooking the cheese omelet!
>>> m.make()
Cooking the mushroom omelet!
>>> c.make()
Cooking the onion omelet!
>>> print(f)
<__main__.Fridge object at 0x000001AAAC643940>
>>> f.has()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: has() missing 1 required positional argument: 'food_name'
>>>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值