码迷,mamicode.com
首页 > 编程语言 > 详细

python类与类之间的关系

时间:2018-12-30 16:25:10      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:__init__   compute   成员   play   cal   --   返回   sel   类型   

在面向对象中,类和类之间也可以产生相关的关系
类中的关系: 依赖关系是最轻的,最重的是继承关系,关联关系是比较微妙的

依赖关系
执行某个动作的时候,需要xxx来帮助完成这个操作,此时的关系是最轻的.
随时可以更换另外一个东西来完成此操作

class Person:
    def f1(self,tools):     # 通过参数的传递把另外一个类的对象传递进来
        tools.run()
        print(皮一下很开心)
class Computer:
    def run(self):
        print(电脑开机运行)
class Phone:
    def run(self):
        print(手机开机)
c = Computer()
a = Phone()
p = Person()
p.f1(a)         #把Phone类的对象a传递给Person的f1方法作为参数
结果
手机开机
皮一下很开心

事例二
植物大战僵尸
class Plant:
    def __init__(self,hp,ad):
        self.hp = hp
        self.ad = ad
    def attack(self,js):
        print(植物攻击僵尸)
        js.hp -= self.ad
        print(f僵尸掉血{self.ad},剩余{js.hp})
class JiangShi:
    def __init__(self,hp,ad):
        self.hp = hp
        self.ad = ad
    def attack(self,zw):
        print(僵尸咬植物)
        zw.hp -= self.ad
        print(f植物掉血{self.ad},剩余{zw.hp})
zw = Plant(100,11)
js = JiangShi(80,15)
zw.attack(js)
zw.attack(js)
js.attack(zw)
js.attack(zw)
结果
植物攻击僵尸
僵尸掉血11,剩余69
植物攻击僵尸
僵尸掉血11,剩余58
僵尸咬植物
植物掉血15,剩余85
僵尸咬植物
植物掉血15,剩余70

关联关系
对象里面包含对象

一对一关系
class Boy:
    def __init__(self,name,girFriend=None):
        self.name = name
        self.girFriend = girFriend
    def play(self):
        if self.girFriend:
            print(f{self.name}带着他女朋友{self.girFriend.name}去吃饭)
        else:
            print(单身狗,还吃什么饭)
    def movie(self):
        if self.girFriend:
            print(f{self.name}带着他女朋友{self.girFriend.name}去看电影)
        else:
            print(单身狗,还看什么电影)
class Girl:
    def __init__(self,name):
        self.name = name
b = Boy(刘昊然)
g = Girl(刘丽)
b.play()

b.girFriend = g
b.play()

g2 = Girl(王萌)
b.girFriend = g2
b.movie()


一对多关系
self.teach_list = [t1,t2,...]
class School:
    def __init__(self,name):
        self.teach_list = []
    def zhaopin(self,teach):
        self.teach_list.append(teach)
    def shangke(self):
        for i in self.teach_list:
            i.work()
class Teacher:
    def __init__(self,name):
        self.name = name
    def work(self):
        print(f{self.name}在上课)
lnh = School(测试)
t1 = Teacher(赵老师)
t2 = Teacher(刘老师)
lnh.zhaopin(t1)
lnh.zhaopin(t2)
lnh.shangke()
结果
赵老师在上课
刘老师在上课

继承关系

class Base:         #父类又叫基类又叫超类
    def chi(self):
        print(吃饭)
class Foo(Base):    #子类又叫派生类,这个类继承了Base类,Foo类是对Base的一个扩展
    def he(self):
        print(喝水)
f = Foo()
f.chi()
f.he()
print(hash(Foo))    #默认类和创建的对象都是可哈希的
print(hash(Foo()))
结果
吃饭
喝水
-9223371912599947772
-9223371912597968945

去掉可哈希
__hash__ = None
class Base:
    def chi(self):
        print(吃饭)
class Foo(Base):
    __hash__ = None     # 当前类的对象不可哈希
    def he(self):
        print(喝水)
f = Foo()
f.chi()
f.he()
print(hash(Foo))    # 类名永远可哈希
print(hash(Foo()))  # TypeError: unhashable type: ‘Foo‘

类名相当于变量名

class Foo:
    def chi(self,food):
        print(吃鱼和,food)
class Bar:
    def chi(self,food):
        print(吃肉和,food)
dic = {Foo:面包,Bar:牛奶}
for k,v in dic.items():
    k().chi(v)
结果
吃鱼和 面包
吃肉和 牛奶

self:谁调用的就是谁,类型是根据调用方的对象来进行变换的
super:表示的是父类

特殊成员:
__init__()  # 创建对象的时候初始化操作
__call__()  # 对象()
__getitem__()   # 对象[哈哈]
__setitem__()   # 对象[哈哈] = 值
__new__()   # 创建对象的时候.开辟内存
__hash__()  # 可哈希 hash()

__call__ 
对象后面加括号,触发执行
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print(__call__)

obj = Foo()  # 执行 __init__
obj()  # 执行 __call__
结果
__call__

事例2
class Foo:
    def __init__(self):                 # 初始化操作
        print(我是init,我是第二)

    def __new__(cls, *args, **kwargs):  # 创建,是真正的构造方法,可以开辟内存
        print(我是new,我是第一)
        return object.__new__(cls)

    def __call__(self, *args, **kwargs): # 对象()   
        print(我是对象call)

    def __getitem__(self, item):        # 对象[]
        print(item,item)
        print(我是getite)

    def __setitem__(self, key, value):  # 对象[key] = value
        print(key,key)
        print(value,value)
Foo()
f = Foo()          # 自动执行__init__()
f()                # 调用__call__()
print(callable(f)) # 对象()
print(f[娃哈哈]) #自动调用__getitem__()
f[]=刘丽     #自动的调用__getitem__()
结果
我是new,我是第一
我是init,我是第二
我是new,我是第一
我是init,我是第二
我是对象call
True
item 娃哈哈
我是getite
None
key 人
value 刘丽


事例3
class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print(del obj[key]时,我执行)
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print(del obj.key时,我执行)
        self.__dict__.pop(item)

f1=Foo(sb)
f1[age]=18
f1[age1]=19
print(f1.__dict__)
del f1.age1
del f1[age]
f1[name]=alex
print(f1.__dict__)
结果
{name: sb, age: 18, age1: 19}
del obj.key时,我执行
del obj[key]时,我执行
{name: alex}


事例4
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    #这个对象字符串的表示
    def __str__(self):  #返回该对象的字符串表示形式
        return f{self.name},{self.age}
    def __repr__(self):  #该对象的官方的字符串表示形式
        return f{self.name},{self.age}
s = Person(bob,18)
print(s)
结果
bob,18

事例5
class B:
    def __str__(self):
        return str : class B
    def __repr__(self):
        return repr : class B
b = B()
print(%s % b)     #这个执行的是__str__函数方法
print(%r % b)     #这个执行的是__repr__函数方法
结果
str : class B 
repr : class B


__del__
析构方法,当对象在内存中被释放时,自动触发执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo:

    def __del__(self):
        print(执行我啦)

f1=Foo()
del f1
print(------->)
结果
执行我啦
------->

 

python类与类之间的关系

标签:__init__   compute   成员   play   cal   --   返回   sel   类型   

原文地址:https://www.cnblogs.com/wangm-0824/p/10199615.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!