面向对象的命名空间;
#属性:静态属性 (直接和类名关联或者直接定义在class下的变量)
# 对象属性 (在类内和self关联,在类外和对象名关联的变量)
# 动态属性(函数)
class Foo: country = "china" def __init__(self,name): self.name = name alex = Foo("alexander") egg = Foo("egon") alex.age = 90 print(Foo.country) print(alex.name) print(alex.age) print(egg.name) print(alex.country) print(egg.country) 输出: china alexander 90 egon china china
class Foo: country = "china" def __init__(self,name): self.name = name alex = Foo("alexander") egg = Foo("egon") alex.age = 90 print(alex.country) print(egg.country) print(Foo.country) alex.country = "印度" print(alex.country) print(egg.country) print(Foo.country) 输出: china china china 印度 china china
class Foo: country = "china" def __init__(self,name): self.name = name alex = Foo("alexander") egg = Foo("egon") alex.age = 90 print(alex.country) print(egg.country) print(Foo.country) alex.country = "印度" print(alex.country) print(egg.country) print(Foo.country) del alex.country #将alex的country属性改回来 print(alex.country) 输出: china china china 印度 china china china
class Foo: country = "china" country_lst = ["China"] def __init__(self,name): self.name = name alex = Foo("alexander") egg = Foo("egon") alex.age = 90 print(alex.country_lst) alex.country_lst.append("印度") print(alex.country_lst) print(egg.country_lst) 输出: ['China'] ['China', '印度'] ['China', '印度']
class Foo: country = "china" country_lst = ["China"] def __init__(self,name): self.name = name alex = Foo("alexander") egg = Foo("egon") alex.age = 90 alex.country_lst = [] print(Foo.country_lst) print(alex.country_lst) 输出; ['China'] []
#类名操作变量 不管操作可变还是不可变数据类型 都是类中对应的变量发生变化
#对象名操作静态变量
#引用变量:现在自己的命名空间中查找,找不到就去类的命名空间找
#修改变量:
# 如果是对可变数据类型中的元素进行修改,那么全局生效
# 如果是对变量进行重新赋值,那么只是在对象自己的命名空间里增加了一个新的属性
# 结论:应该尽量用类名去使用静态变量
# 例子: class Person: money = 0 mother = Person() mother.salary = 20000 mother.money += 20000 # 赚的钱全部进妈妈的私房钱里了 Person.money = Person.money + mother.salary #赚的钱进入家庭存款
设计一个类,统计这个类被实例化的次数,且所有的对象共享这个属性 class Foo: count = 0 def __init__(self): Foo.count += 1 f = Foo() print(f.count) #print(Foo.count) f2 = Foo() print(f2.count) #print(Foo.count) f3 = Foo() print(f3.count) #print(Foo.count) 输出: 1 2 3
class Foo: count = 0 def __init__(self): Foo.count += 1 f = Foo() f2 = Foo() f3 = Foo() print(f.count) #Foo.count print(f2.count) #Foo.count print(f3.count) #Foo.count 三次拿到的都是同一个变量 输出: 3 3 3
class Person: def __init__(self): #给一个什么属性都没有的对象赋一些初识的属性 print("aaaaaa") def eat(self): print('吃猪食') alex = Person() #裸着 print(alex.__dict__) 输出: aaaaaa {}
class Person: def __init__(self): #给一个什么属性都没有的对象赋一些初识的属性 print("aaaaaa") def eat(self): print('吃猪食') alex = Person() #裸着 print(alex.__dict__) alex.eat() #alex.eat ==Person.eat(alex) 输出: aaaaaa {} 吃猪食
#对象使用名字的顺序:先用自己的,再用类的
#对象可以使用类的
#而类无法使用对象的
组合:
#三大特性:封装继承和多态(组合)
#组合 : 什么 有 什么 的关系
#一个对象的属性是另外一个类的对象
老师有生日;
#老师有生日 : 年月日
#将一个类的对象拥有的属性 再将其定义成一个类以提高代码的复用
class Teacher: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex class Brithday: def __init__(self, year, month, day): self.year = year self.month = month self.day = day brithday_gold = Brithday(1968, 4, 1) boss_gold = Teacher("太亮", 48, "不详") boss_gold.brith = brithday_gold print(boss_gold.brith.year) 输出: 1968
方法二:
定义的时候就用到组合:
class Birthday: def __init__(self, year, month, day): self.year = year self.month = month self.day = day class Teacher: def __init__(self, name, age, sex, year, month, day): self.name = name self.age = age self.sex = sex self.birth = Birthday(year, month, day) boss_gold = Teacher("太亮", 48, "不详", 1968, 4, 1) print(boss_gold.birth.year) 输出; 1968
练习:
求一个环的面积和周长:
#圆形类 from math import pi class Circle: def __init__(self, r): self.radius = r def perimeter(self): return 2*pi*self.radius def area(self): return pi*(self.radius**2) #环形类 class Ring: def __init__(self, outer_r, inner_r): self.outer_circle = Circle(outer_r) self.inner_circle = Circle(inner_r) def perimeter(self): return self.outer_circle.perimeter()+self.inner_circle.perimeter() def area(self): return self.outer_circle.area() - self.inner_circle.area() r1 = Ring(10, 5) print(r1.perimeter()) print(r1.area())
人狗大战:(人可以带武器)
class Person: # 定义一个人类 def __init__(self, name, aggressivity, life_value, money): self.name = name # 每一个角色都有自己的昵称; self.aggressivity = aggressivity # 每一个角色都有自己的攻击力; self.life_value = life_value # 每一个角色都有自己的生命值; self.money = money def attack(self, dog): # 人可以攻击狗,这里的狗也是一个对象。 # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降 dog.life_value -= self.aggressivity def get_weapon(self, weapon_obj): if self.money > weapon_obj.price: self.money -= weapon_obj.price # 金老板花钱买武器 self.weapon = weapon_obj # 金老板装备打狗棒 self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了 class Dog: # 定义一个狗类 def __init__(self, name, breed, aggressivity, life_value): self.name = name # 每一只狗都有自己的昵称; self.breed = breed # 每一只狗都有自己的品种; self.aggressivity = aggressivity # 每一只狗都有自己的攻击力; self.life_value = life_value # 每一只狗都有自己的生命值; def bite(self, people): # 狗可以咬人,这里的狗也是一个对象。 # 狗咬人,那么人的生命值就会根据狗的攻击力而下降 people.life_value -= self.aggressivity class Weapon: def __init__(self, name, price, aggr): self.name = name self.price = price self.aggr = aggr dgb = Weapon('打狗棒', 99.8, 100) boss_gold = Person('金老板', 5, 250, 100) huang = Dog('大黄', '藏獒', 100, 3000) boss_gold.get_weapon(dgb) boss_gold.attack(huang) print(huang.life_value)
# 命名空间 :
# 静态属性 : 属于类内部的命名空间
# 动态属性 : 属于类内部的命名空间
# 对象属性 : 属于对象的,在类内和self发生联系,在类外和对象名发生联系
# 可以查看静态属性的都有哪些:类名 对象名
# 可以调用类中的方法的有哪些:类名.方法名(对象),对象.方法名()
# 类到对象之间没有联系,而对象到类之间有联系。
# 对象在查找名的时候,会现在我自己的空间里找,再到类的空间里找