Day23 of learning python--面向对象的命名空间与组合

1.类命名空间与对象命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

类有两种属性:静态属性和动态属性

静态属于就是直接在类中定义的变量,动态属于就是定义在类中的方法

注意:类的静态属性是共享给所有对象的,类的动态属性是绑定到所有对象的

>>>egg.attack
<bound method Person.attack of <__main__.Person object at 0x101285860>>
>>>Person.attack
<function Person.attack at 0x10127abf8> 

 创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

在obj.name会从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类,最后都找不到就抛出异常

# 类定义了两种属性,静态属性和动态属性
class Course:
    language = ['Chinese']
    def __init__(self,teacher,course_name,period,price):
        self.teacher = teacher
        self.name = course_name
        self.period = period
        self.price = price

# Course.language = 'English'  # 修改类的静态属性
# Course.__dict__['language'] = 'Chinese'
# print(Course.language)

python = Course('egon','python','six months',20000)

print(python.language)
# python.language = 'Chinese'   # 在对象自己的名称空间添加一个新的属性,那么以后再查看类中的Course的属性时,是看不到了
print(python.language)
print(python.__dict__)
print(Course.language)

# 类中的静态变量,可以被对象和类调用
# 对于不可变类型变量来说,类变量最好用类名来操作
# 对于可变数据类型来说,修改是共享的,重新赋值是独立的
python.language[0] = 'Chinese'
print(Course.language)
class Foo:
    number = 0
    def __init__(self):
        Foo.number += 1

f1 = Foo()
print(f1.number)
f2 = Foo()
print(f2.number)
print(f1.number)
创建一个类,每实例化一个对象就奇数,最终所有对的对象共享这个数据
# 绑定方法
def func():pass
print(func)

class Fooo:
    def func(self):
        print('func')
f1 = Fooo()
print(Fooo.func)
print(f1.func)  # 当对象调用方法时,这个方法就和对象绑定了,因为f1当作参数传递给了func
print(f1)

<function func at 0x0000023718FED268>
<function Fooo.func at 0x0000023719188730>
<bound method Fooo.func of <__main__.Fooo object at 0x00000237190E5438>>
<__main__.Fooo object at 0x00000237190E5438>

 

注意:对象找属性或者方法最高只能找到类的名称空间,不能找全局的名称空间,包 -- __init__,导入一个包的过程,就是类的实例化过程

2.面向对象的组合用法

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合,能够解决80%的代码

 

class Weapon:
    def prick(self, obj):  # 这是该装备的主动技能,扎死对方
        obj.life_value -= 500  # 假设攻击力是500

class Person:  # 定义一个人类
    role = 'person'  # 人的角色属性都是人

    def __init__(self, name):
        self.name = name  # 每一个角色都有自己的昵称;
        self.weapon = Weapon()  # 给角色绑定一个武器,此处一定是Weapon的实例化,即加()

class Dog:
     def __init__(self,name,life_value):
         self.name = name
         self.life_value = life_value

d1 = Dog('hei',1000)
egg = Person('egon')
egg.weapon.prick(d1)
print(d1.life_value)
# egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法

例子:圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用。

from math import pi

class Circle:
    '''
    定义了一个圆形类;
    提供计算面积(area)和周长(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长

class Ring:
    '''
    定义了一个圆环类
    提供圆环的面积和周长的方法
    '''
    def __init__(self,radius_outside,radius_inside):
        self.outsid_circle = Circle(radius_outside)
        self.inside_circle = Circle(radius_inside)

    def area(self):
        return self.outsid_circle.area() - self.inside_circle.area()

    def perimeter(self):
        return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()


ring = Ring(10,5) #实例化一个环形
print(ring.perimeter()) #计算环形的周长
print(ring.area()) #计算环形的面积

例子2:用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程

class BirthDate:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day

class Couse:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period

class Teacher:
    def __init__(self,name,gender,birth,course):
        self.name=name 
        self.gender=gender
        self.birth=birth
        self.course=course
    def teach(self): 
        print('teaching')

p1=Teacher('egon','male', 
            BirthDate('1995','1','27'), 
            Couse('python','28000','4 months')
           ) 

print(p1.birth.year,p1.birth.month,p1.birth.day) 

print(p1.course.name,p1.course.price,p1.course.period)
''' 
运行结果: 
27 
python 28000 4 months 
'''
posted on 2018-10-25 20:11  smile大豆芽  阅读(160)  评论(0)    收藏  举报