标签:span 需要 没有 不同 就会 实例化 装饰器 内存 之间
属性查找
类有两种属性:数据属性和函数属性
1、类的数据属性是所有对象共享的
# 类的数据属性是所有对象共享的,id是一样的 print(id(OldboyStudent.school)) # 4830576 print(id(s1.school)) # 4830576 print(id(s2.school)) # 4830576 print(id(s3.school)) # 4830576
2、 类的函数属性是绑定给对象用的,称为绑定到对象的方法
# 类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样 print(OldboyStudent.learn) # <function OldboyStudent.learn at 0x0000000002879598> print(s1.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866898>> print(s2.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x00000000028669E8>> print(s3.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866F98>> #ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类,最后都找不到就抛出异常
绑定方法
定义类并实例化出三个对象
class OldboyStudent: school = ‘oldboy‘ def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def learn(self): print(‘%s is learning‘ % self.name) # 新增self.name def eat(self): print(‘%s is eating‘ % self.name) def sleep(self): print(‘%s is sleeping‘ % self.name) s1 = OldboyStudent(‘李坦克‘, ‘男‘, 18) s2 = OldboyStudent(‘王大炮‘, ‘男‘, 28) s3 = OldboyStudent(‘牛弹琴‘, ‘女‘, 38)
类中定义的函数(没有被任何装饰器装饰的)是累的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个函数
OldboyStudent.learn(s1) # 李坦克 is learning OldboyStudent.eat(s2) # 王大炮 is eating OldboyStudent.sleep(s3) # 牛弹琴 is sleeping
类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法
强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将谁本身当做第一个参数转给方法,即自动传值(方法__init__也是一样的道理)
s1.learn() # 等同于OldboyStudent.learn(s1) s2.eat() # 等同于OldboyStudent.eat(s2) s3.sleep() # 等同于OldboyStudent.sleep(s3)
注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写在self
类即类型
Python中一切皆为对象,且Python3中类与类型是一个概念,类型就是类
#类型dict就是类dict >>> list <class ‘list‘> #实例化的到3个对象l1,l2,l3 >>> l1=list() >>> l2=list() >>> l3=list() #三个对象都有绑定方法append,是相同的功能,但内存地址不同 >>> l1.append <built-in method append of list object at 0x10b482b48> >>> l2.append <built-in method append of list object at 0x10b482b88> >>> l3.append <built-in method append of list object at 0x10b482bc8> #操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3 >>> l1.append(3) >>> l1 [3] >>> l2 [] >>> l3 [] #调用类list.append(l3,111)等同于l3.append(111) >>> list.append(l3,111) #l3.append(111) >>> l3 [111]
小节练习
# 练习1:编写一个学生类,产生一堆学生对象, (5分钟) # # 要求: # # 有一个计数器(属性),统计总共实例了多少个对象 class Student(): school = "家里蹲大学" count = 0 def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex Student.count += 1 def learn(self): print(‘%s is learning‘ % self.name) s1 = Student(‘张三‘, ‘男‘, 22) s1.learn() s2 = Student(‘李四‘, ‘女‘, 28) print(Student.count) print(s1.count) # 练习2:模仿三国定义两个英雄类, (10分钟) # # 要求: # # 英雄需要有昵称、攻击力、生命值等属性; # 实例化出两个英雄对象; # 英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡。 class Garen: camp = ‘Demacia‘ def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity if enemy.life_value <= 0: print(‘%s已经死亡‘ % self.nickname) class Riven: camp = ‘Noxus‘ def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity if enemy.life_value <= 0: print(‘%s已经死亡‘ % self.nickname) g1 = Garen(‘曹操‘, 100, 30) r1 = Riven(‘刘备‘, 100, 50) print(r1.life_value) g1.attack(r1) g1.attack(r1) g1.attack(r1) g1.attack(r1) print(r1.life_value)
标签:span 需要 没有 不同 就会 实例化 装饰器 内存 之间
原文地址:https://www.cnblogs.com/mike-liu/p/9128049.html