# 面向对象
# 类:把一类事物的共有的属性和方法整合到一起就是类
# 对象:基于类而创建的一个具体的事物
# 类有两种属性:数据属性和函数属性
# 1. 类的数据属性是所有对象共享的(属性)
# 2. 类的函数属性是绑定给对象用的(方法)
class Person: # 类名一般首字母大写
country = '中国' # 数据属性,所有对象共享
def __init__(self, name, age, gender): # 初始化方法,实例化时会自己执行些方法
self.name = name # self指自己,谁实例化就是谁,后面产生一个实例p,这里就相当于 p.name = name
self.age = age
self.gender = gender
def study(self): # 凡是类中定义的方法,第一个参数必须是self
print('%s在学习' % self.name) # 函数属性
def eat(self, food):
print('%s正在吃%s' %(self.name, food))
print(Person.__dict__) # 查看类的属性字典
print(Person.__name__) # 查看类的名字
print(Person.__base__) # 查看类的第一个父类
print(Person.__bases__) # 查看类的所有父类构成的元组
print(Person.__module__) # 查看类所在的模块
print(Person.__class__) # 查看类对应的类(仅新式类中)
# 实例化(叫做对象或者叫做实例)
p = Person('张三', 18, '男') # 相当于 __init__(p,'张三', 18, '男') p就对应self
# 实例中只保存自己的数据属性,实例调用的方法都是从类中去找的
# 也就是说新创建的实例没有函数属性,可以自行给实例再添加它的函数属性
# 实例调用类中的方法
p.study()
p.eat('面包')
# 类属性的增删改查
# 查看类属性
print(Person.country)
# 修改类属性
Person.country = '美国'
# 增加类属性
Person.newclass = '新类属性的值'
print(Person.newclass)
# 删除类属性
del Person.newclass
print(Person.__dict__) # 属性列表中已经没有newclass了
# 增加函数属性
def run(self): # 先定义一个函数,写法与类中的写法一致
print('%s正在跑步' %self.name)
Person.run = run # 再将刚才定义的函数赋值到Person中的run属性
# 注意不要加括号,加括号相当于调用函数,不加括号就只是传递函数的内存地址
print(Person.__dict__) # 属性列表中已经有run这个函数属性了
# 实例属性的增删改查
# 查看实例的属性列表
print(p.__dict__)
# 查看实列属性
print(p.name)
print(p.age)
print(p.gender)
# 查看实例绑定的类的函数属性
print(p.eat) # 结果为<bound method Person.eat of <__main__.Person object at 0x009FC410>>
# 增加实例的数据属性
p.height = '180cm'
print(p.height)
# 增加实例的函数属性 一般情况下不这样做
def test(): # 这里不需要加上self,因为self是对应类的函数属性的,而不是实例的函数属性
print('我是来自实例的函数属性')
p.test = test
p.test()
# 修改实例的数据属性
p.height = '175cm'
# 删除实例的数据(函数)属性
del p.height
del Person # 删除类
# 注意,在类中定义的属性,需要通过.来查找(.查找只会在类中查找),如果未使用.则会寻找类外的全局变量
num = 10
class Getnum:
num = 20
def __init__(self):
print(self.num) # 这里获取的是类中的num 20
print(num) # 这里获取的是全局变量num 10
n = Getnum()
del Getnum
# 另一个例子
class OtherE:
l = [1, 2]
def __init__(self):
pass
o = OtherE()
o.l.append(3) # 这里使用了append ,因为o里没有l这个列表,所以它操作的是类里的l
o.l = [4, 5] # 这里相当于给o这个实例增加了数据属性l
print(OtherE.l) # [1, 2, 3]
print(o.l) # [4, 5]
del OtherE
# 静态属性 @property 将类中定义的函数属性,通过装饰器@property将其封闭成数据属性
# 可以访问类的所有属性,及实例的所有属性
# 封装以后所有的对该函数的操作,就像是操作数据属性
class Room:
def __init__(self, length, width):
self.length = length
self.width = width
@property
def area(self): #求房间面积的函数属性
return self.length*self.width
r = Room(20, 10)
print(r.area) # 如未封装,我们需要使用r.area()来调用
del Room
# 类方法 @classmethod 不实例化任何对象,直接可以通过类来调用其函数属性,跟实例没任何关系,只是类调用自己的方法
# 可以访问类的数据属性与类的函数属性
class Room:
def __init__(self, length, width):
self.length = length
self.width = width
@classmethod
def area(cls): # 这里参数为cls,表示接收一个类,而不是调用该类的对象self
print('这里是类方法')
Room.area()
del Room
# 静态方法 @staticmethod 只是名义上归属类管理,不能使用类与实例的所有属性,是类的工具包
class Room:
def __init__(self, length, width):
self.length = length
self.width = width
@staticmethod
def area():
print('这里是静态方法')
Room.area()
r = Room(200, 100)
r.area() # python3.6.5可以这样调用
del Room
# 类的组合 用于做类与类之间的关联(类与类之间无共同点),比如组合一个人
class Hand:
pass
class Foot:
pass
class Body:
pass
class Head:
pass
class Person:
def __init__(self, id, name):
self.id = id
self.name = name
self.Hand = Hand()
self.Foot = Foot()
self.Body = Body()
self.Head = Head()