Python学习之路-面向对象

面向对象编程

类与对象

class 类名:

    属性

类名.属性

类名的作用:操作属性  查看属性

对象 = 类名()

过程:

     类名()首先会创造出一个对象,创建一个self变量

     调用init方法,类名括号里的参数会被质量接收

     执行init方法

     返回self

调用方法 :

    类名.方法名(对象名) 

    对象名.方法名

对象能做的事

    查看属性

    调用方法

    __dict__对于对象的增删改查操作都可以通过字典的语法进行

类名能做的事:

    实例化

    调用方法 要自己传递self参数

    调用类中的属性,也就是调用静态属性

    __dict__类中的名字只能看 不能操作

self

一个可以存储很多属性的大字典

往字典里添加属性的方式改变了一些变化

class Dog:
    def __init__(self,name,blood,aggr,kind):
        self.name = name
        self.hp = blood
        self.aggr = aggr
        self.kind = kind

    def bite(self, person):
        person.blood -= self.aggr
        if person.blood <= 0:
            print('%s咬了%s,%s被打死了'%(self.name,person.name,person.name))
        else:
            print('%s咬了%s,掉了%s的血'%(self.name,person.name,self.aggr))
class Person:
    def __init__(self, name, blood, aggr, sex):
        self.name = name
        self.blood = blood
        self.aggr = aggr
        self.sex = sex
    def attack(self,dog):
        dog.hp -= self.aggr
        if dog.hp <= 0:
            print('%s打了%s,%s被打死了'%(self.name,dog.name,dog.name))
        else:
            print('%s打了%s,掉了%s的血'%(self.name,dog.name,self.aggr))
jin = Dog('金老板',100,20,'teddy')
alex =Person('alex',999,998,'不祥')
jin.bite(alex)
print(alex.blood)
alex.attack(jin)
print(jin.hp)
View Code
class Person:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def hiking(self):
        print('姓名:%s,年龄:%s,性别:%s,喜欢爬爬山'%(self.name,self.age,self.sex))

    def drive(self):
        print('姓名:%s,年龄:%s,性别:%s,喜欢开车'%(self.name,self.age,self.sex))

    def favor(self):
        print('姓名:%s,年龄:%s,性别:%s,喜欢看电视'%(self.name,self.age,self.sex))

ming = Person('小明',20,'')
ming.hiking()
ming.drive()
ming.favor()
View Code
class Circle:
    def __init__(self,r):
        self.r = r
        
    def area(self):
        return pi*self.r**2
    
    def perimeter(self):
        return 2*pi*self.r


c1 = Circle(5)
print(c1.area())
print(c1.perimeter())
View Code
class Square:
    def __init__(self, le):
        self.le = le

    def area(self):
        return self.le*self.le

    def perimeter(self):
        return self.le*4


s = Square(3)
print(s.area())
print(s.perimeter())
View Code

非常明显的处理一类事物,这些事物都具有想死的属性和功能

当有几个函数需要反复传入相同的参数的时候,可以考虑面向对象

这些参数都是对象的属性

类和对象的命名空间

类中的静态变量可以被对象和类调用

对于不可变数据类型,类变量最好用类名操作

对于可变数据类型,修改是共享的,重新赋值是独立的

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'
print(Course.language)
python = Course('egon', 'python', '6 month', 20000)
linux = Course('oldboy', 'linux', '6 month', 20000)
print(python.language)
print(linux.language)
python.language = 'Chinese'
print(python.language)
print(linux.language)
print(python.__dict__)
print(linux.__dict__)
View Code
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[0] = 'English'
# print(Course.language)
python = Course('egon', 'python', '6 month', 20000)
linux = Course('oldboy', 'linux', '6 month', 20000)

# print(python.language)
# print(linux.language)
python.language[0] = 'English'
print(python.language)
print(linux.language)
print(Course.language)
print(python.__dict__)
print(linux.__dict__)
# ['English']
# ['English']
# ['English']
# {'teacher': 'egon', 'name': 'python', 'period': '6 month', 'price': 20000}
# {'teacher': 'oldboy', 'name': 'linux', 'period': '6 month', 'price': 20000}
修改
python.language = ['English']
print(python.language)
print(linux.language)
print(Course.language)
print(python.__dict__)
print(linux.__dict__)
# ['English']
# ['Chinese']
# ['Chinese']
# {'teacher': 'egon', 'name': 'python', 'period': '6 month', 'price': 20000, 'language': ['English']}
# {'teacher': 'oldboy', 'name': 'linux', 'period': '6 month', 'price': 20000}
重新赋值
class Foo:
    count = 0

    def __init__(self):
        Foo.count += 1
f1 = Foo()
f2 = Foo()
print(f1.count)
print(f2.count)
f3 = Foo()
print(f1.count)
View Code

绑定方法

def func():pass
print(func)

class Foo:
    def func(self):
        print('func')
f1 =Foo()
print(Foo.func)
print(f1.func)
# <function func at 0x0000027994822A60>
# <function Foo.func at 0x0000027994822E18>
# <bound method Foo.func of <__main__.Foo object at 0x0000027994821588>>
View Code

 组合

在一个对象的属性值是另外一个类的对象

from math import pi

class Circle:
    def __init__(self,r):
        self.r = r

    def area(self):
        return pi*self.r**2

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

class Ring:
    def __init__(self,outside_r,inside_r):
        self.outside_c = Circle(outside_r)
        self.inside_c = Circle(inside_r)

    def area(self):
        return self.outside_c.area() - self.inside_c.area()

    def perimeter(self):
        return self.outside_c.perimeter() - self.inside_c.perimeter()


ring = Ring(20,10)
print(ring.area())
print(ring.perimeter())
组合例子
class Dog:
    def __init__(self,name,aggr,hp,kind):
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.kind = kind

    def bite(self,person):
        person.hp -= self.aggr


class Person:
    def __init__(self,name,aggr,hp,sex):
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.sex = sex
        self.money = 0

    def attack(self,dog):
        dog.hp -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print('余额不足,请充值')


class Weapom:
    def __init__(self,name,aggr,njd,price):
        self.name = name
        self.aggr = aggr
        self.njd = njd
        self.price = price

    def hand18(self, person):
        if self.njd > 0:
            person.hp -= self.aggr*2
            self.njd -= 1


alex = Person('alex',0.5,100,'不祥')
jin = Dog('jin',100,500,'不祥')
w = Weapom('打狗棒',100,3,998)
alex.money += 1000
alex.get_weapon(w)
print(alex.weapon)
print(alex.aggr)

alex.attack(jin)
print(jin.hp)
alex.weapon.hand18(jin)
print(jin.hp)
View Code
class Teacher:
    def __init__(self,name,age,sex,birthday):
        self.name = name
        self.age = age
        self.sex = sex
        self.birthday = birthday
        self.course = Course(self,'python','6个月','20000')
b = Birthday(2018,1,16)
egg = Teacher('egon',0,'',b)
print(egg.name)
print(egg.birthday.year)
print(egg.course.price)
View Code

继承

正常代码中 单继承  减少了代码的重复

继承表达的是一种子类是父类的关系

class A:pass     父类、基类、超类

class B(A)       子类、派生类

一个类 可以被多个类继承

一个类可以继承多个父类 --Python里

__bases__查看继承关系

没有继承父类默认继承object,是所有类的父类

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp


class Dog(Animal):

    def bite(self,person):
        person.hp -= self.aggr


class Person(Animal):

    def attack(self,dog):
        dog.hp -= self.aggr


jin = Dog('jin',200,500)
print(jin.name)
View Code

派生属性、派生方法

父类中没有的属性,在子类中出现,叫派生属性

父类中没有的方法,在子类中出现,叫派生方法

只要子类的对象调用,子类中有的名字,一定用子类的,子类中没有才找父类

如果还想用父类的,单独调用父类的

                                父类名.方法名 需要自己传self参数

                                super().方法名 不需要自己传self

单继承

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def eat(self):
        print('吃药回血')
        self.hp += 100


class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        Animal.__init__(self,name,aggr,hp)
        self.kind = kind  #派生属性

    def eat(self):
        Animal.eat(self)#如果既想实现新的功能,也想使用父类原有的功能,还需要再调用一次父类
        self.teeth = 2
    def bite(self,person):
        person.hp -= self.aggr


class Person(Animal):
    def __init__(self,name,aggr,hp,sex):
        Animal.__init__(self, name, aggr, hp)  
        self.sex = sex
        self.money = 0

    def attack(self,dog):
        dog.hp -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print('余额不足,请充值')


jin = Dog('',100,500,'teddy')
jin.eat()
print(jin.hp)

# alex = Person('alex',100,200,'男')
# alex.eat()
# print(alex.hp)
# jin.bite(alex)
# print(alex.hp)
View Code

super

class Animal:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def eat(self):
        print('吃药回血')
        self.hp += 100


class Dog(Animal):
    def __init__(self,name,aggr,hp,kind):
        super().__init__(name,aggr,hp) #只在新试类中有,python3中所有的类都是新试类
        self.kind = kind  #派生属性
    def eat(self):print('dog eating')
jin = Dog('',200,500,'tt')
print(jin.name)
jin.eat()
super(Dog,jin).eat()
#
# dog eating
# 吃药回血
View Code

多继承

不会超过三个父类,如果子类有 用自己的,如果没有就用离子类最近的那个父类的方法

python2.7 新试类和经典类共存

python3 只要新试类,默认继承object

新试类 继承object类才是新试类 广度有限

经典类 如果创建一个类在2.7中国就是经典类 深度优先

super只在python3中存在, mro方法只在新试类中存在

super的本质,不是直接找父类,而是根据调用者的节点位置的广度有限顺序来的

接口类 

满足接口隔离原则 面向对象开发的思想规范

接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些不需要的接口

from abc import abstractmethod,ABCMeta

 

python原生不支持,默认多继承,接口类中的所有方法都有必须不实现

from abc import abstractmethod,ABCMeta


class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        raise NotImplemented

class Wechat(Payment):
    def pay(self,money):
        print('已经使用微信支付了%s元'%money)


class ALipay(Payment):
    def pay(self,money):
        print('已经使用支付宝支付了%s元'%money)

class APPlepay(Payment):
    def fuqian(self,money):
        print('已经使用苹果支付了%s元'%money)

def pay(pay_obj,money):
    pay_obj.pay(money)

# wechat = Wechat()
# ali = ALipay()
app =APPlepay()
# pay(wechat,100)
# pay(ali,200)
View Code

接口类的多继承

from abc import abstractmethod,ABCMeta

class Swim_Animal(metaclass=ABCMeta):
    @abstractmethod
    def swim(self):
        pass


class Walk_Animal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):
        pass

class Fly_Animal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):
        pass

class Tiger(Walk_Animal,Swim_Animal):pass
class Eagle(Fly_Animal,Walk_Animal):pass
class Swan(Swim_Animal,Walk_Animal,Fly_Animal):pass
接口类的多继承

抽象类 python原生支持

不支持多继承,抽象类中的方法可以有一些代码的实现

一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的功能实现

多继承的情况 由于功能比较复杂,不容易抽象出相同的功能的具体实现写在父类中

抽象类,接口类:面向对象的开发规范,

python中没有接口类,java里有接口Intereface这个概念

python字典多继承 可以直接用class来实现接口类

python支持抽象类: 一般情况下单继承且可以实现代码 不能实例化

# 操作系统中 一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        with open('filaname') as f:
            pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')
    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)
抽象类

多态 一类事物有多种形态

python天生支持多态

多态性 在不考虑实例类型的情况下使用实例

class ALipay():
    def pay(self,money):
        print('已经使用支付宝支付了%s元'%money)


class APPlepay():
    def fuqian(self,money):
        print('已经使用苹果支付了%s元'%money)

def pay(pay_obj,money):
    pay_obj.pay(money)
多态

鸭子类型:不崇尚根据继承所得来的相似,自己实现自己的代码,如果两个类刚好相似,并不产生父类的兄弟关系,而是鸭子类型 eg:list tuple 这种相似,是自己写代码的时候约束的,而不是通过父类约束的

优点:松耦合,每个相似的类之间都没有影响

缺点:过于随意

强类型语言  多态

python语言 鸭子类型

接口类和抽象类  在python当中的应用点并不是非常重要

封装

广义上面向对象的封装:代码包含,蜜饯相对性的思想本身就是一种,只让自己的对象调用自己累中的方法

狭义上的封装

属性和方法藏起

所有的私有 在变量的左边加上双下划线,都不能在类的外部使用

   对象的私有属性

   类中的私有方法

   类中的静态属性

父类的私有属性不能被子类调用

用到私有概率的场景:

隐藏起一个属性,不想让类的外部调用

保护属性,不想让属性随意被改变

保护属性,不被子类继承

property 装饰器函数,只在面向对象中使用

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def perimeter(self):
        return 2*pi*self.r
    @property
    def area(self):
        return self.r**2*pi

c1 = Circle(4)
print(c1.area)
print(c1.perimeter)
property
class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):
        return self.__name + 'sb'
    @name.setter
    def name(self,new_name):
        self.__name = new_name

tai = Person('tai')
print(tai.name)
tai.name = '全部'
print(tai.name)
setter,修改
class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):
        return self.__name
    @name.deleter
    def name(self):
        del self.__name

brother2 = Person('二哥')
print(brother2.name)
del brother2.name
print(brother2.name)  #报错 属性被删除
deleter与del 关联,删除

静态方法 staticmethod

在完全面向对象的程序中,既和对象没有关系 也和类没有关系 那么就用staticmethod将这个函数变成一个静态方法

class Login:
    def __init__(self,name,password):
        self.name = name
        self.password = password
    def login(self):pass
    @staticmethod 
    def get_user_pwd():
        use = input('用户名:')
        pwd = input('密码:')
        Login(use,pwd)

Login.get_user_pwd()
staticmethod

类方法 classmethod

class Goods:
    __discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod
    def change_discount(cls,new_discount):
        cls.__discount = new_discount
apple = Goods('苹果',5)
print(apple.price)
Goods.change_discount(0.5)  
print(apple.price)
classmethod

把一个方法 变成一个类中的方法,这个方法就直接可以被调用,不需要依托任何对象

当这个方法的操作至设计静态属性的时候,就应该使用classmethod来装饰这个方法

类方法和静态方法 都是类调用的 

对象可以调用 类方法和静态方法,一般情况下推进用类名调用

类方法有一个默认参数 cls 代表这个类

静态方法没有默认参数 就像函数一样

反射

getattr 

class Teacher:
    dic = {'查看学生信息':'','查看讲师信息':''}
    def show_student(self):
        print('show_student')
    def show_teacher(self):
        print('show_teacher')
    @classmethod
    def func(selfcls):
        print('ff')
#hasattr getattr delattr
ret = getattr(Teacher,'dic')  #Teacher.dic
ret2 = getattr(Teacher,'func')   #Teacher.func
print(ret)
print(ret2)
ret2()
# {'查看学生信息': '', '查看讲师信息': ''}
# <bound method Teacher.func of <class '__main__.Teacher'>>
# ff
getattr

hasattr

class Teacher:
    dic = {'查看学生信息':'','查看讲师信息':''}
    def show_student(self):
        print('show_student')
    def show_teacher(self):
        print('show_teacher')
    @classmethod
    def func(selfcls):
        print('ff')
#hasattr getattr delattr
if hasattr(Teacher,'dic'):
    ret = getattr(Teacher,'dic')  #Teacher.dic
    print(ret)
hasattr

delattr

isinstance(obj,cls)检查obj是否是cls类的对象

issubclass(sub,super)检查sub是否是super的子类

class A:pass
class B(A):pass
a = A()
print(isinstance(a,A))
print(issubclass(B,A))
# True
# True
isinstance、issubclass

反射:用字符串类型的名字,去操作变量

反射对象中的属性和方法  hasattr getattr setattr delattr

反射对象的属性

class A:
    def func(self):
        print('in func')


a = A()
a.name = 'alex'
ret = getattr(a,'name')  # 通过变量min的字符串 形式取到的值
print(ret)
变量名 = input('>>>')
print(getattr(a,变量名))
反射对象的属性

反射对象的方法

class A:
    def func(self):
        print('in func')


a = A()
ret = getattr(a,'func')
ret()
反射对象的方法

反射类的属性和方法

class A:
    price = 20
    @classmethod
    def func(self):
        print('in func')

print(getattr(A,'price'))
if hasattr(A,'func'):
    getattr(A,'func')()
反射类的属性和方法

反射模块的属性

import my
print(my.day)
print(getattr(my,'day'))
反射模块属性

反射模块的方法

import my
ret = getattr(my,'whh')
ret()
反射模块方法

内置函数也能使用反射

反射自己模块中的变量和模块中的函数

def qq():
    print('qq')
year = 2019
import sys
# print(sys.modules['__main__'].year)
print(getattr(sys.modules['__main__'],'year'))
getattr(sys.modules['__main__'],'qq')()
反射自己模块中的变量和函数
def qq():
    print('qq')
year = 2019
import sys
变量名 = input('>>')
print(getattr(sys.modules[__name__],变量名))
View Code

反射的函数有参数  在函数字符串后面加上参数即可

import time
print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(getattr(time,'strftime')('%Y-%m-%d %H:%M:%S'))
View Code

一个模块中的类可以被反射得到

import my
getattr(my,'C')()
View Code

if hasattr():

    getattr()

setattr 设置 修改变量

class A:
    pass
a = A()
setattr(A,'name','alex')
setattr(a,'name','a')
print(A.name)
print(a.name) 
View Code

delattr  删除一个变量

class A:
    pass
a = A()
setattr(A,'name','alex')
setattr(a,'name','a')

delattr(a,'name')
print(a.name)

几个内置方法

obj.__str__  obj.repr__

object 里有一个__str__,一定被调用就返回调用这个方法对象的内存地址

__str__  打印一个对象的时候,就是调用对象.__str__

class A:
    def __str__(self):
        return 'A`s object'

a = A()
print(a)  # A`s object
__str__
class Teacher:
    def __init__(self,name,salary):
        self.name = name
        self.salary = salary
    def __str__(self):
        return 'Teacher`s object:%s'%self.name
    def func(self):
        return 'www'

na = Teacher('哪吒',250)
print(na)  #Teacher`s object:哪吒
View Code

__repr__

class Teacher:
    def __init__(self,name,salary):
        self.name = name
        self.salary = salary
    def __str__(self):
        return 'Teacher`s object:%s'%self.name
    def __repr__(self):
        return str(self.__dict__)
    def func(self):
        return 'www'

na = Teacher('哪吒',250)
print(na)  #Teacher`s object:哪吒
print(repr(na))  # {'name': '哪吒', 'salary': 250}
print('%r'%na)  # {'name': '哪吒', 'salary': 250}
__repr__

%s str() 直接打印 实际上都是走的__str__

%r repr() 实际上是走的__repr__

repr 是str的备胎,但str不能做repr的备胎

str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么返回的必定是一个字符串

如果没有__str__方法,会找本类中的__repr__方法,再没有,再找父类中的__str__

repr(),只会找__repr__,如果没有就找父类的

__del__ 

析构函数 删除一个对象之前,进行一些收尾工作

__call__ 

一个对象加上括号,调用__call__

class A:
    def __del__(self):  # 析构函数
        print('执行了')
a = A()
a.f = open()
lst = []
for i in range(1000):
    lst.append(A())
a = lst.pop()
import time
time.sleep(3)
print(a)
del a  #  执行了这个方法,又删除了变量
print(a)

class A:
    def __init__(self,name):
        pass
    def __call__(self):
        print('执行了')

a = A('alex')
a()
__del__ __call__

item系列  用于类似字典的操作

__getitem__

__setitem__

__delitem__

class Foo:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def __getitem__(self, item):
        if hasattr(self,item):
            return self.__dict__[item]

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]

f = Foo('egon',38,'')
print(f['name'])
f['hobby'] = ''
print(f.hobby,f['hobby'])
del f['hobby']
print(f.__dict__)
item系列

__new__  构造方法 创建一个方法

class A:
    def __init__(self):
        self.x = 1
        print('in init')
    def __new__(cls, *args,**kwargs):
        print('in new')
        return object.__new__(A,*args,**kwargs)

a = A()
print(a.x)
__new__

单例模式 一个类始终只有一个实例

class A:
    __instance = False
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __new__(cls, *args,**kwargs):
        if cls.__instance:
            return cls.__instance
        cls.__instance = object.__new__(A)
        return cls.__instance

a = A('rgg',23)
a.cloth = '衣服'
b = A('na',25)
print(b)
print(a)
print(b.name)
print(a.name)
print(b.cloth)
# <__main__.A object at 0x0000026A8E0A7A58>
# <__main__.A object at 0x0000026A8E0A7A58>
# na
# na
# 衣服
单例模式

当你第一次实例化这个类的时候就创建一个实例化的对象

当你之后再实例化的时候 就业之前创建的对象

__hash__

class A:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
    def __hash__(self):
        return hash(self.name+self.sex)

a = A('egon','')
b = A('egon','')
print(hash(a))
print(hash(b))
# -237336835754499130
# -237336835754499130

a = A('egon','')
b = A('egon','nan')
print(hash(a))
print(hash(b))
# 4366271411327963305
# 4193967196857736331
__hash__

__eq__

class A:
    def __init__(self,name):
        self.name = name

    def __eq__(self, other):
        if self.name == other.name:
            return True
        else:
            return False

obj1 = A('egg')
obj2 = A('egg')
print(obj1 == obj2)#True
__eq__

猜你喜欢

转载自www.cnblogs.com/rssblogs/p/10976518.html