类、对象

1 python中的任何一条数据都是对象,每个对象都由3部分组成:标识、类型和值。

对象的标识代表该对象在内存中的存储位置 不可更改,对象的类型表明它可以拥有的数据和值的类型。在对象中,可变类型的值可以更改,不可变类型的值不能更改

2 类允许定义一组对象,并将它们封装到一个方便的空间中。

3 使用dir函数可以列举出一个对象的所有属性和方法 dir(fridge)

以下划线开关的名称是对象的私有属性,它们是不可见的。即不能直接使用它们

 函数内置到一个对象中时,它叫做这个对象的方法

函数len就是利用方法__len__工作的:函数len向这个内置方法询问对象的长度。对象的设计者可定义长度的计算方式,使得对于定义了__len__方法的任何对象,内置函数len都能够正确运行

4 通过 class 关键字声明类 并在后面紧跟一个名称来完成

class Fridge:

"""this class implements a fridge """

类的名称以大写字母开头是惯例。当类的名称有多个单词时,每个词以大写字母开头以方便阅读。

5使用一对圆括号调用Fridge类,可以创建一个对象:f=Fridge()

class Fridge:
""" this class is a fridge
methods: has(food_name[,quantity]) checks if the string food_name is in the fridge. quantity will be set to 1 if you do not specify a number.
has_various(foods) check if enough of every food in the dictionary is in the fridge
add_one(food_name) adds 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 passed an object that has the __ingredients__ method,get_many will invoke this to get the list 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):
""" adds more than one of a food item.returns the numer 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
raise a TypeError is 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):
""" 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

运行文件后 使用 类

>>> f=Fridge({"eggs":6,"milk":4,"cheese":3})
>>> f.items
{'eggs': 6, 'milk': 4, 'cheese': 3}
>>> f.add_one("grape")
True
>>> f.items
{'eggs': 6, 'milk': 4, 'cheese': 3, 'grape': 1}
>>> f.add_many({"mushroom":5,"tomato":4})
>>> f.add_many({"mushroom":5,"tomato":4})
>>> f.items
{'eggs': 6, 'milk': 4, 'cheese': 3, 'mushroom': 10, 'tomato': 8}

 使用记事本的tab 长度与 在shell中的tab长度不一致,则在记事本中写入程序后 ,在shell中再写入后面的程序,运行报错

保持接口行为不变的能力叫做类的稳定性

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 the type named
set_new_kind(kind,ingredients) lets you create an omelet
mix() gets called after all the ingredients are gathered from the fridge
cook() cooks the omelet"""

def __init__(self,kind="cheese"):
""" this initialized the omelet class to default to 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

运行文件 使用类制作

>>> 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!

 在类中使用的函数叫做方法,每个类都有一个特殊的名称self,当self被调用时,它包含对象中所有的数据和方法。

使用类的名称并在后面跟着圆括号() 来创建该类的对象,此时可以给定初始化参数,新创建的对象调用方法__init__,参数包括 可选的、默认的参数

类中的方法通常可分为两类:一类是公共接口,应当在对象外部调用,另一类是私有方法,应当只能被对象内部的其他方法调用。接口应当尽量不变,而内部 私有方法可以改变,而不影响类的使用方法。python认为在对象作用域内,以两个下划线开头的任何名称都是私有属性。其他名称 般被认为是公共 。

为了详细说明类的使用方法,应当为这个类创建文档字符串,即在类定义后的第一行输入一个字符串。文档字符串最好能够提供期望被使用的方法的名称和用途。

类中定义的所有名称(数据和方法)在每个创建的对象中都不同。当一个对象调用某个方法时,该方法改变那个对象中的数据,而同一类型的其他对象则不受影响。

为了使对象易用,通常提供行为类似的多个接口。为了节省工作,这些接口可以找到调用内部方法的一些方式,而内部方法比它们更复杂,接收更多的参数。这有两个好处。第一调用这些方法的代码更易读,程序员不必记住参数的名称,因为方法的名称本身就提供了程序员所需 信息。第二,只改变内部方法就可以改变所有相关接口的行为。

编写对象的一个目的是尽量少编写重复代码,而是提供尽量多的特性。创建使用对象的类可以节省大量输入,因为它们通常比数据和函数分开更易于操作,原因在于同一个类中的方法总是可以确定它们使用的其他方法和数据是存在的。可以写一组相互依赖的类,对相互协作的事物建模

原文地址:https://www.cnblogs.com/caojuansh/p/11493271.html