一、命名空间
属性:静态属性 (直接和类名关联或者直接定义在class下的变量)
对象属性 (在类内和self关联,在类外和对象名关联的变量)
动态属性(函数)
1、类的静态属性调用
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
其中类的数据属性是共享给所有对象的
class Foo: country = '中国'
def __init__(self,name):
self.name = name
alex = Foo('alexander') # 实例化对象
egg = Foo('egon')
print(Foo.country) # 中国
print(alex.country) # 中国 先找alex对象的内存,再找Foo的内存
print(egg.country) # 中国
alex.country = '印度'
print(Foo.country) # 中国
print(alex.country) # 印度
print(egg.country) # 中国
2、给对象创建属性
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
class Foo:
country = 'China' # 静态属性 类属性
country_lst = ['China']
def __init__(self,name): # 动态属性
self.name = name # 对象属性
alex = Foo('alexander') # 实例化对象
egg = Foo('egon') # 实例化对象
alex.age = 90 # 给对象创建一个age属性
print(alex.age) # 90
集合
class Foo:
country = 'China' # 静态属性 类属性
country_lst = ['China']
def __init__(self,name): # 动态属性
self.name = name # 对象属性
alex = Foo('alexander')
egg = Foo('egon')
alex.age = 90 # 给对象创建一个age的属性
alex.country_lst = []
alex.country_lst.append('印度')
print(alex.country_lst) # ['印度']
print(Foo.country_lst) # ['China']
Foo.role = 'Person'
print(Foo.country) # China
print(alex.name) # alexander
print(egg.name) # egon
alex.country = '印度'
print(alex.country) # 印度
print(egg.country) # China
print(Foo.country) # China
del alex.country # 删除印度,重新指向
print(alex.country) # China
print(alex.country_lst) # ['印度']
类名操作变量
不管操作可变还是不可变数据类型 都是类中对应的变量发生变化
对象名操作静态变量
引用变量:
先在自己的命名空间中查找,找不到就去类的命名空间找
修改变量:
如果是对可变数据类型中的元素进行修改,那么全局生效
如果是对变量进行重新赋值,那么只是在对象自己的命名空间里增加了一个新的属性
结论:应该尽量用类名去使用静态变量
对象名的使用顺序
class Person:
def __init__(self):pass # 初始化
#给一个什么属性都没有的对象赋一些初识的属性
def eat(self):
print('吃米饭')
alex = Person() #裸着
print(alex.__dict__)
alex.eat() # 吃米饭
alex.name = 'alexander'
alex.eat = '喝粥' #对象使用名字的顺序:先用自己的,再用类的
# alex.eat() # 报错,括号里加字符串错误
#对象可以使用类的
#而类无法使用对象的
print(Person.eat) # <function Person.eat at 0x0000000001E88A60>
print(alex.eat) #类对象指针的东西 alex = {'eat':eat}
# 喝粥
二、面向对象组合
在一个类中以另一个类的对象做为数据属性,称为类的组合
例题、
例1:计算圆环的面积和周长
#圆形类
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()
ring1 = Ring(20,10)
print(ring1.area()) # 面积
print(ring1.perimeter()) # 周长
# 既能hold住圆形的问题 # 又能解决环形的问题 函数方式
10,20def func(arg1,arg2):
outer_circle = Circle(20)
inner_circle = Circle(10)
print(outer_circle.area() - inner_circle.area())
def func2(arg1,arg2):
outer_circle = Circle(20)
inner_circle = Circle(10)
print(outer_circle.perimeter() + inner_circle.perimeter())
# 500个环
ring1 = Ring(20,10)
ring1.area()
例2、
老师有生日
class Teacher:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
# self.birth_year = year
class Birthday:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
birthay1 = Birthday(1968,12,31)
boss_gold = Teacher('lishi',40,'girl')
boss_gold.birth = birthay1
print(boss_gold.birth.year) # 1968
print(boss_gold.birth.month) # 12
print(boss_gold.birth.day) # 31
print(boss_gold.name) # lishi
print(boss_gold.sex) # girl
升级版
人,生日,课程
class Birthday:
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day
class Course:
def __init__(self,name,price,teacher):
self.name=name
self.price=price
self.teacher=teacher
class Person:
def __init__(self,name,birth,course):
self.name=name
self.birth=birth
self.course=course
B=Birthday(1999,12,24)
C=Course('python',20000,'jing')
haijiao=Person('haijiao',B,C)
print(haijiao.name) #haijiao
print(haijiao.birth.year) #1999
print(haijiao.birth.month) #12
print(haijiao.birth.day) #24
print(haijiao.course.name) #python
print(haijiao.course.price) #20000
print(haijiao.course.teacher) #jing
3、人狗大战续集
#狗
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 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 # 金老板的攻击力增加了
# boss_gold = Person('金老板',5,250,100)
# huang = Dog('大黄','藏獒',100,3000)
# huang.bite(boss_gold)
# print(boss_gold.life_value)
# boss_gold.attack(huang)
# print(huang.life_value)
#不公平
#武器装备
#人 有 武器 —— 组合
#武器:攻击力,名字,价格
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)
面试题
设计一个类,统计这个类被实例化的次数,且所有的对象共享这个属性
一、
class Foo:
count = 0
def __init__(self):
Foo.count += 1
f = Foo()
print(f.count) # 1
f2 = Foo()
print(f.count) # 2
f3 = Foo()
print(f.count) # 3
二、
class Foo:
count = 0
def __init__(self):
Foo.count += 1
f = Foo()
f2 = Foo()
f3 = Foo()
print(f.count) #Foo.count 3
print(f2.count) #Foo.count 3
print(f3.count) #Foo.count 3