面向对象命名空间及组合(面试题)

 

命名空间 :
静态属性 : 属于类内部的命名空间
动态属性 : 属于类内部的命名空间
对象属性 : 属于对象的,在类内和self发生联系,在类外和对象名发生联系
可以查看静态属性的都有哪些:类名 对象名
可以调用类中的方法的有哪些:类名.方法名(对象),对象.方法名()
类到对象之间没有联系,而对象到类之间有联系。
对象在查找名的时候,会现在我自己的空间里找,再到类的空间里找

 

一、命名空间

属性:静态属性 (直接和类名关联或者直接定义在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,20 def 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

 

 
posted @ 2017-11-20 16:58  小杜要加油  阅读(460)  评论(0编辑  收藏  举报