面向对象(类)的简易使用
作者:爱吃肉的小花生
首先声明:写这些只是方便做着自己记忆和理解,如果能帮助到大家那当然更好不过
一、类的编码风格
(1)类的名字用驼峰命名法,类名首字母大写,不能有下划线
(2)类所包含的方法名全部小写,用下划线将单词隔开
(3)方法与方法用一个空行隔开,类与类用两个空行隔开
(4)在类和方法的下一行给其一个注释,告诉自己他们的简易功能,方便自己查阅和调用
(5)导入类的时候,先导入标准库中的,然后隔行在导入自己创建的类
二、类的建立与访问其属性
python2与python3的使用方法略有不同,因为我是使用3的,这里就只讲述python3有关类的使用方法
1、创建并使用类
我们举个例子餐馆,创建一个名为 Restaurant 的类,描述餐馆的名称、烹饪属性(cuisine type)还有营业状态。
class Restaurant():
'''一次模仿饭店的尝试'''
def __init__(self,restaurant_names,cuisine_types):
'''_init_是一种固定的方法,self也是固定的形参,必不可少,必须放到首位!!'''
self.restaurant_name = restaurant_names
self.cuisine_type = cuisine_types
def describe_restaurant(self):
'''描述饭店的名称烹饪种类'''
print("The restaurant name is : "+self.restaurant_name.title())
print("The cuisine type is : "+self.cuisine_type.title())
def open_restaurant(self):
'''指出饭店的营业状态'''
print(self.restaurant_name+' is open !')
注意事项:
(1)class 类名() : 创建一个类, 这里类名首字母大写,和函数一样,创建过后给其一个注释,目的主要是方便我们以后查阅 。
(2)self是固定的形参,必不可少,因为我们在使用方法是会自动传入实参self的
(3)这里我们创建的类比较简单,主要是为了把创建的框架让大家理解一下
2、创建实例并使用
restaurant1 = Restaurant("quanjude",'peking_duck')
restaurant1.describe_restaurant()
restaurant1.open_restaurant()
'''创建一个实例并使用'''
restaurant2 = Restaurant("kfc",'snack')
restaurant2.describe_restaurant()
restaurant2.open_restaurant()
'''创建第二个实例,并使用它'''
使用的方法和函数类似, 实例的名称.函数()即可,下面附上结果:
The restaurant name is : Quanjude
The cuisine type is : Peking_Duck
quanjude is open !
The restaurant name is : Kfc
The cuisine type is : Snack
kfc is open !
类是可以反复使用的,可以创建多个实例来使用
二、给属性默认值,修改属性的值
1、通过方法(函数)修改属性的值
给属性默认值跟函数里给形参一个默认值的方法是类似的,修改属性的第一种方法是直接修改,类似于函数里的关键字实参,在此这两个方面就不再赘述,以免让大家觉得无趣,下面我们讲一下用方法(我的理解就是类里面的函数)来改变属性的值。还是上面全聚德的例子,我们再给其加一个属性“就餐过的人数”:
class Restaurant():
'''一次模仿饭店的尝试'''
def __init__(self,restaurant_names,cuisine_types,number_served=0):
self.restaurant_name = restaurant_names
self.cuisine_type = cuisine_types
self.number = number_served
def describe_restaurant(self):
'''描述饭店的名称烹饪种类'''
print("The restaurant name is : "+self.restaurant_name.title())
print("The cuisine type is : "+self.cuisine_type.title())
print("就餐过的人数为:"+str(self.number))
def open_restaurant(self):
'''指出饭店的营业状态'''
print(self.restaurant_name+' is open !')
def set_number(self,people_number):
'''设置就餐过的人数'''
self.number = people_number
print("就餐过的人数为:"+str(people_number))
def increment_number_served(self,increment):
'''就餐人数的增量'''
self.number += increment
我们number_served设置了默认值为0,可以直接修改,那就调用的时候输入对应的位置实参或者关键字实参即可,如:
restaurant1.Restaurant(‘quanjude’,‘pekingduck’,9)
但是很显然饭店的服务人数不会不变的,毕竟有很多我这样的emmmm爱吃肉的人嘛,那如果我们一次一次输入,就显得很繁琐,所以在下面我添加了一个set_number()和increment_number_served()的方法,以便我们去修改这个属性的值。我再调用的时候最后一行是:
restaurant1.increment(33)
却发现输出结果仍为9人,这是为什么呢?其实原因很简单,值已经修改过来了,但是我没有调用describe_restaurant()这个函数,只要我们最后调用的是这样就可以了:
restaurant1.increment(33)
restaurant1.describe_restaurant()
这样输出结果就是9+33=42了。
为防止大家模糊,我们再做个简要的例子,我们对一个网站的访问者做一个简单的尝试,有姓名,访问次数这几个属性,通过increment_login_number( )来逐渐递增尝试访问的次数,reset_login_number( )来重置访问的次数为0。
class User():
'''一次模仿访问者的尝试'''
def __init__(self,first_name,last_name,login_attempts):
'''访问者的姓名信息和尝试访问次数'''
self.name = first_name.title()+' '+last_name
self.login_attempt = login_attempts
def describe_user(self):
'''输出访问者的简要介绍'''
print("The abstract is : "+self.name)
def greet_user(self):
'''对访问者进行简单的问候'''
print("Hello "+self.name)
print(self.login_attempt)
def increment_login_attempts(self):
'''尝试访问的次数的增加'''
self.login_attempt += 1
def reset_logign_number(self):
'''重置访问的次数'''
self.login_attempt = 0
'''我在做这一步尝试的时候,值总是没有重置为0而是一直保持原样
我试了半天,才发现我打的是self.login_attempts=0 就多了一个s
花了我接近15分钟的时间'''
格式和上面的饭店的格式是类似的,其实我个人理解的类就是几个函数复合起来的一个大函数,为了方便我们使用,像是一个大的分类,我们为其定义了种类。
三、继承
我们在这只讲一下简单的继承问题,复杂的继承问题如多态等,后面我们会深入挖掘,继承顾名思义,子承父业,一个类可以包含子类,我们举例子说比如我们创建一个动物类,在动物类下,我们有创建了狗这个类,那么狗就是动物的子类。那我们拿上面饭馆举个例子,创建一个子类冰淇淋加工厂,它继承了饭店的所有属性,而且有自己独有的属性flavor。
class Restaurant():
'''一次模仿饭店的尝试'''
def __init__(self,restaurant_names,cuisine_types):
self.restaurant_name = restaurant_names
self.cuisine_type = cuisine_types
def describe_restaurant(self):
'''描述饭店的名称烹饪种类'''
print("The restaurant name is : "+self.restaurant_name.title())
print("The cuisine type is : "+self.cuisine_type.title())
def open_restaurant(self):
'''指出饭店的营业状态'''
print(self.restaurant_name+' is open !')
class IceCreamStand(Restaurant):
'''一次冰淇淋加工厂的尝试'''
def __init__(self,restaurant_names,cuisine_types):
#重新初始化属性值,注意__init__是两道下划线,一共四道
#我在第一次尝试的时候,只打了一道,找错找了2个小时
super().__init__(restaurant_names,cuisine_types)
self.flavors = ['a','b','c','d','e']
def show_icecreams(self):
for flavor in self.flavors:
print("The icecream is "+flavor)
icecream1 = IceCreamStand('beauty girl','ice')
icecream1.show_icecreams()
'''这两行是创建的实例,并使用它,附上运行结果:'''
'''The icecream is a
The icecream is b
The icecream is c
The icecream is d
The icecream is e
'''
这里又要注意的地方是:
(1)我们先初始化了属性值,也就是 def init(self, ,)这个函数,我们一定要注意是左右两边两道下划线,我第一次尝试的时候,找错找了两个小时,最后发现是打的一条下划线,在pycharm中你打一道并没有显示格式的错误,只是颜色与两道的不一样,所以大家在使用的时候一点更要注意,是左右两道下划线哦
(2) super().init(restaurant_names,cuisine_types) ,super()后面是子类承接的属性。
(3)我报的错是:AttributeEorror: the object has no attribute。
我们可以通过在子类里命名一个与父类相同名字的方法进而重写父类的方法,这样在调用时会直接使用子类里的方法
下面我们再尝试几个例子,用上面访问人员的类,再创建一个管理员的子类,并且多了一个privilege的独有属性,我们来看看该如何实现
class User():
'''一次模仿访问者的尝试'''
def __init__(self,first_name,last_name,login_attempts):
'''访问者的姓名信息和尝试访问次数'''
self.name = first_name.title()+' '+last_name
self.login_attempt = login_attempts
def describe_user(self):
'''输出访问者的简要介绍'''
print("The abstract is : "+self.name)
def greet_user(self):
'''对访问者进行简单的问候'''
print("Hello "+self.name)
print(self.login_attempt)
def increment_login_attempts(self):
'''尝试访问的次数的增加'''
self.login_attempt += 1
def reset_logign_number(self):
'''重置访问的次数'''
self.login_attempt = 0
class Admin(User):
'''一次管理员的简单尝试'''
def __init__(self,first_name,last_name,login_number):
super().__init__(first_name,last_name,login_number)
self.privileges = ['can add post','can delete post','can ban user']
def show_privilege(self):
'''展示管理员的特权'''
for self.privilege in self.privileges:
print("Your privileges is "+self.privilege)
admin1 = Admin('james','frank',8)
admin1.show_privilege()
下面我们再另写一个Privilege类,只存放privilege属性,并将show_privilege()方法放入其中
class User():
'''一次模仿访问者的尝试'''
def __init__(self,first_name,last_name,login_attempts):
'''访问者的姓名信息和尝试访问次数'''
self.name = first_name.title()+' '+last_name
self.login_attempt = login_attempts
def describe_user(self):
'''输出访问者的简要介绍'''
print("The abstract is : "+self.name)
def greet_user(self):
'''对访问者进行简单的问候'''
print("Hello "+self.name)
print(self.login_attempt)
def increment_login_attempts(self):
'''尝试访问的次数的增加'''
self.login_attempt += 1
def reset_logign_number(self):
'''重置访问的次数'''
self.login_attempt = 0
class Admin(User):
'''一次管理员的简单尝试'''
def __init__(self,first_name,last_name,login_number):
super().__init__(first_name,last_name,login_number)
self.privileges = Privilege()
class Privilege():
'''对特权的一个尝试'''
def __init__(self,privileges=['can add post','can delete post','can ban user']):
'''我们可以这么表示,也可以只写privilege,
然后在上面self.privileges=Privilege()加入属性值是一样的'''
self.privileges = privileges
def show_privilege(self):
'''展示管理员的特权'''
for self.privilege in self.privileges:
print("Your privileges is "+self.privilege)
admin1 = Admin('james','frank',8)
admin1.privileges.show_privilege()
我么们把另一种方法也用代码表达出来,这里我们只给出了一段:
class Admin(User):
'''一次管理员的简单尝试'''
def __init__(self,first_name,last_name,login_number):
super().__init__(first_name,last_name,login_number)
self.privileges = Privilege(['can add post','can delete post','can ban user'])
class Privilege():
'''对特权的一个尝试'''
def __init__(self,privileges):
self.privileges = privileges
def show_privilege(self):
'''展示管理员的特权'''
for self.privilege in self.privileges:
print("Your privileges is "+self.privilege)
admin1 = Admin('james','frank',8)
admin1.privileges.show_privilege()
输出结果是一样的,最后调用实例时,都是找privilege的值,一个是在Privilege类里,一个是在Admin里。
四、导入类
1、导入单个类
from Users import User
'''第一个Users是模块名,User是导入的类名'''
user1 = User('frank','james',9)
user1.describe_user()
2、从一个模块中导入多个类
from 模块名 import 类名1,类名2,类名3
'''用逗号将类名隔开'''
3、导入模块的所有类,用*号
4、导入模块到模块中,一般父类导入到子类中
我们举个复合的例子,将上面的Admin放到一个模块中,User放到一个模块中
from Users import User
'''先将父类导入在子类模块中
否则在导入子类是,调用会报错'''
class Admin(User):
'''一次管理员的简单尝试'''
def __init__(self,first_name,last_name,login_number):
super().__init__(first_name,last_name,login_number)
self.privileges = Privilege(['can add post'])
class Privilege():
'''对特权的一个尝试'''
def __init__(self,privileges):
self.privileges = privileges
def show_privilege(self):
'''展示管理员的特权'''
for self.privilege in self.privileges:
print("Your privileges is "+self.privilege)
from Admin类 import Admin,Privilege
admin1 = Admin('james','frank',8)
admin1.privileges.show_privilege()
再导入子类,并创建实例调用即可。
导入的模块若是对父类有依赖性,要先将父类的模块导入子类模块中,再去导入子类模块!!!
五、Python标准库
标准库是其他程序员写的类,方便我们使用,具体信息我们可以查阅http://pymotw.com/
我们举一个randint的例子生成整数随机数,在模块random中
from random import randint
n = 0
while n <=10:
n += 1
x = randint(1,6)
print(x)
两种方法是一样的。
from random import randint
for i in range(1,11):
x = randint(1,6)
print(x)
其他的标准库我们还需要仔细查阅,这里我们只讲了一个简单的小例子。