面向对象 类与对象及其属性与方法 类的组和

# 面向对象
# 类:把一类事物的共有的属性和方法整合到一起就是类
# 对象:基于类而创建的一个具体的事物

# 类有两种属性:数据属性和函数属性
# 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()

猜你喜欢

转载自www.cnblogs.com/dangrui0725/p/9452602.html