一 、定义类
# def 函数名 ( 形参 ):
# 函数执行的内容
# 类的格式
# class 类名 ( 父类 ):````
# 类的内容
# 类名后面有括号的类,称为新式类;
# 括号里面的内容是父类的名称;程序中,所有类的父类都是 object;
class Animals(object):
pass
print(Animals)
/usr/local/python3/bin/python3.6 /home/kiosk/PycharmProjects/day_08/04_面向对象操作.py
<class '__main__.Animals'>
二、类的属性
class Animals(object):
## 类的数据属性
name = "westos"
age = 18
print(Animals)
## 访问类的数据属性
print(Animals.name)
print(Animals.age)
/usr/local/python3/bin/python3.6 /home/kiosk/PycharmProjects/day_08/04_面向对象操作.py
<class '__main__.Animals'>
westos
18
三、类的方法
class Animals(object):
name = "fentiao"
age = 12
weight = 10
# 类的方法 ==== 函数
# 在类中定义的函数叫做方法 ;
# 类的方法中, python 解释器要求第一个形参必须是 self ;与 java 中的 this 类似;
# self 实质上是类实例化后的对象本身 ;
def eat(self):
print("eating......")
print(self)
# 类的实例化产生的就是对象; 把抽象的类创造出实际存在的事物;
# object: 对象
fentiao = Animals()
print(fentiao)
# 调用类的方法
fentiao.eat()
/usr/local/python3/bin/python3.6 /home/kiosk/PycharmProjects/day_08/04_面向对象操作.py
<__main__.Animals object at 0x7f40cf1624e0>
eating......
<__main__.Animals object at 0x7f40cf1624e0>
对于每一个对象特色化设置;
class Cat(object):
# 构造方法;当实例化对象时会自动执行;
def __init__(self,name,age,weight):
# self实质是一个对象;self=> westos;
# attribute:属性; 把属性和对象绑定在一起, westos.name可以获取到姓名
self.name = name
self.age = age
self.weight = weight
# 类里面的函数第一个参数是self时,pyhton解释器自动将对象传给self变量;
def eat(self):
self.weight += 2
print("%s is eating,now weight is %s" %(self.name,self.weight))
# 实例化对象
westos = Cat('westos',18,100)
print(westos.name)
print(westos.age)
print(westos.weight)
westos.eat()
fendai = Cat('fendai', 5, 10)
print(fendai.name)
print(fendai.age)
print(fendai.weight)
/usr/local/python3/bin/python3.6 /home/kiosk/PycharmProjects/day01/02_面向对象操作.py
westos
18
100
westos is eating,now weight is 102
fendai
5
10
四、面向对象的三大特性: 封装, 继承, 多态
1.面向对象的封装
class Cat(object):
def __init__(self, name, age, weight):
# 封装: 将属性均绑定在self变量上;
self.name = name
self.age = age
self.weight = weight
# 类里面的函数第一个参数时self, 并且pyhton解释器自动将对象传给self变量;
def eat(self): # java: this
self.weight += 2
print("%s is eating, now weight is %s" %(self.name, self.weight))
直接调用:
westos = Cat('westos',18,100)
print(westos.name)
间接调用
# 通过self间接调用(只能在类中调用)
self.name
2.面向对象的继承和多态
父类和子类; 基类和派生类;
继承:子类继承父类的方法
注意: 类的属性名和方法名不同相同;
建议:
属性名用名词;eg:name, age, weight;
方法名建议用动词; eg: eat, drink, get_weight;
多态:当父类和子类有同一方法时, 优先执行子类的方法;
# Cat没有__init__函数, 则调用父类的构造函数;如果父类没有, 则找父类的父类,
# 依次类推, 一直没有, 则不执行;
class Animals(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print("%s is eating..." %(self.name))
# Cat类的父类是Animals;
class Cat(Animals):
# # 去执行父类的构造函数;
# Animals.__init__(self, name, age)
def eat(self):
print('cat %s is eating' %(self.name))
westos = Cat('westos',18)
westos.eat()
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/01_类的特性继承.py
cat westos is eating
执行Cat父类的构造函数, 不包含父类的任何信息;
如果Cat的父类变化, 无需进入类里面修改;
class Animals(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print("%s is eating..." %(self.name))
# Cat类的父类是Animals;
class Cat(Animals):
def __init__(self,name,age,fishcount):
# 执行Cat父类的构造函数, 不包含父类的任何信息;
# 如果Cat的父类变化, 无需进入类里面修改; super(Cat,self).__init__(name,age)
self.fishcount = fishcount
# 多态: 当父类和子类有同一方法时, 优先执行子类的方法;
def eat(self):
# Animals.eat(self)
super(Cat,self).eat()
self.fishcount -=2
print('cat %s is eating,now have fish %s' %(self.name,self.fishcount))
westos = Cat('westos',18,100)
westos.eat()
westos.eat()
# 父类没有drink方法, 则不能执行;
westos.drink()
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/01_类的特性继承.py
westos is eating...
cat westos is eating,now have fish 98
westos is eating...
cat westos is eating,now have fish 96
## 报错:Cat类无drink方法
Traceback (most recent call last):
File "/root/PycharmProjects/day09/01_类的特性继承.py", line 34, in <module>
westos.drink()
AttributeError: 'Cat' object has no attribute 'drink'
多重继承
对于新式类来说, 多重继承的算法是广度优先 ;
深度优先:继承父类,直到没有父类
class D(object):
def test(self):
print("D test")
class C(D):
pass
# def test(self):
# print("C test")
class B(D):
pass
# def test(self):
# print("B test")
# A 继承 B 和 C ;
class A(B,C):
pass
# def test(self):
# print("A test")
# 继承顺序(广度优先:就近原则)
A -> B -> D
-> C -> D
a = A()
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/03_多重继承.py
D test
class D(object):
def test(self):
print("D test")
class C(D):
# pass
def test(self):
print("C test")
class B(D):
pass
# def test(self):
# print("B test")
class A(B,C):
pass
# def test(self):
# print("A test")
a = A()
a.test()
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/03_多重继承.py
C test
class D(object):
def test(self):
print("D test")
class C(D):
pass
# def test(self):
# print("C test")
class B(D):
pass
# def test(self):
# print("B test")
class A(B,C):
# pass
def test(self):
print("A test")
a = A()
a.test()
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/03_多重继承.py
A test
五 、新式类和经典类
python2.x里面支持经典类和新式类;
python3.x里面仅支持新式类;
新式类:广度优先 A -> B,C -> (B->D)|(C->D)
经典类:深度优先 A -> B -> D -> C -> D
# - 经典类
class Book1:
pass
# - 新式类
class Book2(object):
pass
六、类操作
1.特殊的类属性
class Base(object):
pass
class Animals(object):
"""
父类Animals:
Attritube:
name:
age:
weight:
"""
def __init__(self, name, age, weight):
self.name = name
self.age = age
self.weight = weight
def eat(self):
print("%s eating......" % (self.name))
self.weight += 2
class Cat(Animals):
def eat(self):
print("%s eating......" % (self.name))
self.weight += 1
class Dog(Animals, Base):
def eat(self):
print("%s eating......" % (self.name))
self.weight += 3
print(Animals.__name__)
print(Animals.__doc__)
# 打印类的所有父类 , 以元组类型返回 ;
print(Animals.__bases__)
print(Dog.__bases__)
# 以字典的方式返回类的方法和属性 ;
print(Animals.__dict__)
# 如果类不是被导入的, 显示为 __main__;
# 如果类是被 import 导入的, 则显示类所在的模块名
print(Animals.__module__)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
Animals
父类Animals:
Attritube:
name:
age:
weight:
(<class 'object'>,)
(<class '__main__.Animals'>, <class '__main__.Base'>)
{'__module__': '__main__', '__doc__': '\n 父类Animals:\n Attritube:\n name:\n age:\n weight:\n ', '__init__': <function Animals.__init__ at 0x7f4791a7e0d0>, 'eat': <function Animals.eat at 0x7f4791a7e158>, '__dict__': <attribute '__dict__' of 'Animals' objects>, '__weakref__': <attribute '__weakref__' of 'Animals' objects>}
__main__
2.类属性
私有属性: 只能在类中使用的属性(双下划线__)
self.__state = state
私有方法: 只能在类中使用的方法(双下划线__)
def get__state(self):
class Book(object):
# 构造函数,在实例化对象时自动执行;
def __init__(self,name,author,state,BookIndex):
# oop的特性:封装
self.name = name
self.author = state
# 0: 未借出, 1代表借出
self._state = state
self.BookIndex = BookIndex
def __str__(self):
# 实质是对象的字符串显示;
# 当str(对象名)会自动调用;
# print(对象名)也会自动调用
if self.state == 0:
state = "未借出"
if self.state == 1:
state = "借出"
return "Book(%s, %s, %s)" %(self.name, self.author, state, self.BookIndex)
b1 = Book('python','guido',0,'IN45')
b1._state = 1
print(b1._state)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
1
class Book(object):
# 构造函数,在实例化对象时自动执行;
def __init__(self,name,author,state,BookIndex):
# oop的特性:封装
self.name = name
self.author = state
# 0: 未借出, 1代表借出
self.__state = state ##私有属性,类外部不能调用
self.BookIndex = BookIndex
def get__state(self): ##私有方法,类外部不能调用
# 实质是对象的字符串显示;
# 当str(对象名)会自动调用;
# print(对象名)也会自动调用
if self.__state == 0:
return "未借出"
if self.__state == 1:
return "借出"
def set__state(self,value): ##私有方法,类外部不能调用
if value in [0,1]:
self.__state = value
return True
else: ##raise:抛出异常
raise Exception("状态值只能为0或1")
b1 = Book('python','guido',0,'IN45') ##实例化
print(b1.get_state()) ##查看结果 ##调用函数繁琐
b1.set_state(1) ## 修改状态值
print(b1.get_state())
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
未借出
借出
print(b1.get_state())
b1.set_state(2) ##2不符合state要求,会抛出异常
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
未借出
Traceback (most recent call last):
File "/root/PycharmProjects/day09/04_类属性.py", line 85, in <module>
b1.set_state(2)
File "/root/PycharmProjects/day09/04_类属性.py", line 77, in set_state
raise Exception("状态值只能为0或1")
Exception: 状态值只能为0或1
3.类属性装饰器 @property
# 类属性: @property
class Book(object):
# 构造函数,在实例化对象时自动执行;
def __init__(self, name, author, state, BookIndex):
# oop的特性:封装
self.name = name
self.author = author
# 0: 未借出, 1代表借出
# 私有属性: 只能在这个类里面使用的属性;
self.__state = state
self.BookIndex = BookIndex
@property # 代表state不是方法, 而是一个属性值, b1.state
def state(self):
if self.__state == 0:
return "未借出"
if self.__state == 1:
return "借出"
@state.setter # ##book.state = value 赋值或修改
def state(self, value):
# if value == 0 or value == 1:
if value in [0,1]:
self.__state = value
return True
else:
# 抛出异常:
raise Exception("状态值只能为0或1")
b1 = Book('python', 'guido', 0, 'IN45')
print(b1.state)
b1.state = 1
print(b1.state)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
未借出
借出
4.类方法和静态方法
class Date(object):
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def date_show(self): ##self是对象
print("""
Year:%s
Month:%s
Day:%s""" % (self.year, self.month, self.day))
@classmethod ##默认第一个参数是类名
def date_str(cls, str): ##类方法,传入cls,实质是Date类;str 为 object
if '-' in str:
year, month, day = str.split('-')
if '/' in str:
month, day, year = str.split('/')
return cls(year, month, day)
@staticmethod ##静态方法,pyhton解释器不会传入任何参数
def date_is_vaild(str):
if '-' in str:
year, month, day = map(int, str.split('-'))
if '/' in str:
month, day, year = map(int, str.split('/'))
return year > 0 and 0 < month <= 12 and 0 < day <= 31
##针对不同类型的输入方式实例化
date1 = Date(2018,6,9) ##以int型数字实例化
date1.date_show()
date2 = Date.date_str('2018-6-9') ##以str型实例化
date2.date_show()
date3 = Date.date_is_vaild('6/88/2018') ##简易判断日期是否合法
print(date3)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
Year:2018
Month:6
Day:9
Year:2018
Month:6
Day:8
False
5.类的自省
type(d1) ##查看d1的类型
isinstance(d1,Date) ##查看d1是否为Date类
dir(d1) ##查看d1的用法
d1.__class__ ##查看d1的类名
d1.__doc__ ##查看d1的解释说明
d1.__dict__ ##查看d1的属性,字典形式列出
hasattr(d1,'year') ##d1是否具有year属性
getattr(d1,'year') ##查看d1的year属性的值
getattr(d1,'year','YEAR') ##若没有year属性,则输出YEAR
setattr(d1,'year',2000) ##将d1的year属性值改为2000
from collections import Iterable
class Date(object):
"""this is Date class"""
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def get_date(self):
return self.day
d1 = Date(2018, 6, 8)
isinstance(5,int) ## int类 ——> 对象 5
print(isinstance(d1,Date)) ## Date类 ——> 对象 d1
print(isinstance("hello",(Date,str,Iterable))) ##类Date,str,Iterable --> 对象"hello"
# type 判断类型
print(type(d1))
# dir 查询对象的魔术方法
print(dir(d1))
print(d1.__class__) ## d1的类
print(d1.__doc__) ## d1的函数说明
print(d1.__dict__) ## 对象属性及其对应的值,类型为字典
# hasattr 判断对象的属性是否存在 存在:True 不存在:False
print(hasattr(d1,'year'))
print(hasattr(d1,'yea'))
# getattr 获取对象属性的值,属性不存在时,报错
print(getattr(d1,'year'))
# print(getattr(d1,'yre'))
# 当对象的hello属性不存在时,自动返回westos
print(getattr(d1,'hello','westos'))
# setattr 修改对象属性的值
setattr(d1,'year',2019)
print(getattr(d1,'year'))
## 判断两对象是否相等
# d1.__eq__(d2)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day09/04_类属性.py
True
True
<class '__main__.Date'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'day', 'get_date', 'month', 'year']
<class '__main__.Date'>
this is Date class
{'year': 2018, 'month': 6, 'day': 8}
True
False
2018
westos
2019