面向对象的命名空间;

#属性:静态属性 (直接和类名关联或者直接定义在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发生联系,在类外和对象名发生联系
    # 可以查看静态属性的都有哪些:类名 对象名
    # 可以调用类中的方法的有哪些:类名.方法名(对象),对象.方法名()
    # 类到对象之间没有联系,而对象到类之间有联系。
    # 对象在查找名的时候,会现在我自己的空间里找,再到类的空间里找