面向对象-内置函数和内置方法

python内置函数

isinstance(obj,class)   

判断一个对象是否是已知的类型,类似type()

isinstance语法:isinstance(object,classinfo)
  • object 是实例/对象
  • classinfo 可以是直接或间接类名,基本类型或者由他们组成的元组
返回值

如果对象的类型与classinfo相同,返回bool值True,否则返回False

 

isinstance 与type的区别:
  • type()不会认为子类是一种父类类型,不考虑继承关系
  • isinstance() 会认为子类是一种父类类型,考虑继承关系,

如果要判断两个类型是否相同的时候尽量用isinstance()

示例1:

a = [1,2,3] print(isinstance(a,list))
输出: True


示例2:

class
A(object):pass class B(A):pass b=A() print(isinstance(b,A)) # 返回True b 是 A 的对象 print(type(b) is B) # 返回False b不是B类的对象 print(type(b) is A) #type 在这里是检测对象是不是类的对象/实例

issubclass( ) 

  判断两个类是否有继承关系,,如果真的有继承关系,那就返回bool值True/False

 

class A(object):pass
class B(A):pass
print(issubclass(B,A))  # True  B类是A类的子类
print(issubclass(A,B))  # False

内置方法

什么是内置方法?

内置方法也叫双下方法,魔术方法,它们在python中处处皆是,它们是一些可以让你对类添加"魔法"的特殊方法,经常都是双下划线包围来命名的比如(__init__,__str__)等等,到现在还是没有很好的办法来解释它们.

内置方法的特点

一定有某一个语法或者一种写法自动触发这个方法.

常见常用的内置方法

最常见的__init__ 是个初始化方法,类的初始化方法, 然而当我们执行 a =class()的时候,__init__并不是 第一个被调用的方法,事实上__new__第一个被调用,这个方法才真正的创建了实例/对象,当这个对象生命周期结束的时候,这时候__del__方法会被调用.看到这样的联系,让我们进一步了解他们的特性!

__new__  也叫构造方法,__(cls,[...)__  它提供了一个实例化对象的时候所需要的内存空间 例如--->创建空间

首先说说设计模式中的单例模式,  __new__是对象实例化的时候第一个被调用的方法,它只取cls也就是类的参数,把其他参数传给__init__..

单例模式示例1

class Teacher2:
    flag = None  #静态属性为空
    def __new__(cls, *args, **kwargs):
        if cls.flag is None:  #执行判断 cls.flag 也就是Teacher2类的静态属性为空的情况下
            cls.flag = object.__new__(cls)   #这句话直走一次
            #Teacher2继承的父类 object.__new__(cls)开辟/构建的空间地址赋予Teacher2类的静态属性
            print(cls.flag)
        return cls.flag   #类的静态属性得到的空间地址赋值Sheldon2

Sheldon2 = Teacher2()
ssa = Teacher2()  #当ssa执行实例化的时候,flag 已经不等于None,而等于一个空间地址, 不走if判断,直接把原先的空间地址赋值给ssa

单例模式示例2

class Teacher:
    flag = None
    def __new__(cls,*args,**kwargs):  #
        if cls.flag is None:
            cls.flag = object.__new__(cls)
        return cls.flag
    
    def __init__(self,name):
        self.name = name

Sheldon = Teacher('Sheldon')
Penny = Teacher('Penny')
print('Sheldon.name')   #输出  Sheldon
print('Penny.name')    #输出  Penny
print('Sheldon.name')  ##输出  Penny

__init__   (self[...)  类初始化方法  实例化

它获取任何传给构造器的参数,(例如Sheldon = Teacher('Sheldon')  __init__ 就会接收到参数Sheldon.  __init__在python类的定义中用的最多

__del__ (self)  析构方法

__del__ 是对象的销毁器,它并不是实现了语句中 del Sheldon 因此它并不等于 Sheldon.__del__(), 而是定义了对象的垃圾回收时的行为,当对象需要销毁时做的一些处理的时候,这个方法会用到,

class Teacher:
    def __init__(self,name):
        self.name = name
    def __del__(self):
        print('执行删除动作')

Sheldon = Teacher('Sheldon')
print('11111')
# 输出顺序 11111 ---> 执行删除动作 ---> 删除Sheldon
del Sheldon  #  执行del 对象的时候触发了__del__ ,在真正删除Sheldon对象前,执行方法__del__
            # 如果我们不删除 Sheldon ,那么程序的执行过程中或最后,垃圾回收机制会替你执行del Sheldon
            # del Sheldon ---> 执行__del--->删除Sheldon

__call__(self[args...)  可调用的对象

你可能已经知道了,在Python中,函数是一等的对象。这意味着它们可以像其他任何对象一样被传递到函数和方法中,这是一个十分强大的特性。

允许类的一个实例像函数那样被调用。本质上这代表了 a() 和 a.__call__() 是相同的。注意 __call__ 可以有多个参数,这代表你可以像定义其他任何函数一样,定义 __call__ ,喜欢用多少参数就用多少。

class Student:
    def __init__(self,name,sex):
        self.name = name
        self.sex =sex
    def __call__(self, *args, **kwargs):
        print('执行调用了')
Sheldon = Student('Sheldon','male')
# callable() 查看某个变量是否能被调用
#callable(变量) 返回True 意味着 变量()--->调用
print(callable(Student))  #类可以被调用
print(callable(Sheldon))  # 对象可以被调用
Sheldon()  #执行__call__方法 
View Code

 __str__ (self) 定义类的实例调用str()的行为

能在打印对象的时,不输出无用的内存地址,输出你需要的格式化字符串

常用写法: 1.  print(对象)    2.str(对象)  3.'%s'%对象

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

    def __str__(self):  #必须有一个返回值,必须返回一个str类型
        return '%s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
course_lst = []
python = Course('python',1111,'12','Sheldon')
linux = Course('linux',2222,'12','Lins')
print(python)   # 写法1
print(str(python)) # 写法2
print('课程展示 : %s'%python)  # 写法3
course_lst.append(python)
course_lst.append(linux)
for course in course_lst:
    print(course)   # 直接展示所有课程

__repr__ (self)    是__str__(self) 的备胎,(有str就调用str,没有str调用repr)

定义对类的实例调用repr()时的行为,str()和repr()最大的区别在于'目标用户',repr()的作用是产生机器可读的输出,(大部分情况下,输出可作为python有效代码),而str()则产生人类可读输出

示例1

class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __repr__(self): # 必须有返回值,必须返回一个str类型
        return 'repr --> : %s,%s,%s,%s' % (self.name, self.price, self.period, self.teacher)

python = Course('python',1111,'12','Sheldon')
linux = Course('linux',2222,'12','Lins')
print('%r'%python)
print('%s'%python)
print(str(python))
print(repr(python))
#全部输出  repr可以输出str方法
repr --> : python,1111,12,Sheldon
repr --> : python,1111,12,Sheldon
repr --> : python,1111,12,Sheldon
repr --> : python,1111,12,Sheldon

示例2

class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    # def __repr__(self): # 必须有返回值,必须返回一个str类型
    #     return 'repr --> : %s,%s,%s,%s' % (self.name, self.price, self.period, self.teacher)

python = Course('python',1111,'12','Sheldon')
linux = Course('linux',2222,'12','Lins')
print('%r'%python)
print('%s'%python)
print(str(python))
print(repr(python))
#输出  str只能输出str方法,无法输出repr方法
<__main__.Course object at 0x00000000027E15C0>
str --> : python,1111,12,Sheldon
str --> : python,1111,12,Sheldon
<__main__.Course object at 0x00000000027E15C0>
View Code

__unicode__(self)   不常用,但是跟__str__ ,__repr__

定义对类的实例调用 unicode() 时的行为。 unicode() 和 str() 很像,只是它返回unicode字符串。注意,如果调用者试图调用 str() 而你的类只实现了 __unicode__() ,那么类将不能正常工作。所有你应该总是定义 __str__() .

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

    def __unicode__(self): # 必须有返回值,必须返回一个str类型
        return 'unicode --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)

python = Course('python',1111,'12','Sheldon')
linux = Course('linux',2222,'12','Lins')
print('%r'%python)
print('%s'%python)
print(str(python))
print(repr(python))
#全部输出  unicode可以输出str,repr方法,但是是unicode字符串类型
<__main__.Course object at 0x00000000027C15C0>
<__main__.Course object at 0x00000000027C15C0>
<__main__.Course object at 0x00000000027C15C0>
<__main__.Course object at 0x00000000027C15C0>
View Code

容器背后的魔法

item系列方法

  • __getitem__(self,item)    表达方式 :obj.['xxx'] == >obj.xxx

定义对容器中某一项的使用self[key] 的方式进行读取操作时的行为。这也是可变和不可变容器类型都需要实现的一个方法。它应该在键的类型错误式产生 TypeError 异常,同时在没有与键值相匹配的内容时产生 KeyError 异常。

  • __setitem__(self,key,value)     表达方式:obj['xxx'] =yyy   ---> obj.xxx=yyy

定义对容器中某一项使用 self[key] 的方式进行赋值操作时的行为。它是可变容器类型必须实现的一个方法,同样应该在合适的时候产生 KeyError 和 TypeError 异常。  __iter__(self, key) 它应该返回当前容器的一个迭代器。迭代器以一连串内容的形式返回,最常见的是使用 iter() 函数调用,以及在类似 for x in container: 的循环中被调用。迭代器是他们自己的对象,需要定义 __iter__ 方法并在其中返回自己。

  • __delitem__(self,key)   del obj['xxx'] ===>  del obj.xxx

定义对容器中某一项使用 self[key] 的方式进行删除操作时的行为。 

class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __len__(self):
        return len(self.__dict__)
    def __getitem__(self, item):
        return self.__dict__[item]
    def __setitem__(self, key, value):
         self.__dict__[key] = value
    def __delitem__(self, key):
        self.__dict__.pop(key)
python = Course('python',1111,'12','Sheldon')
linux = Course('linux',2222,'12','Lins')
print(len(python))  # 输出 4
print(python['name'])  # 输出 python
print(python['price'])  # 输出 1111
python['name'] = 'python.2.0'  # 针对python.name 进行修改
print(python.name)  # python.2.0  发现已经被修改
del python['name'] # 执行删除python.name 操作
print(python.__dict__)  # {'price': 1111, 'period': '12', 'teacher': 'Sheldon'} 查看 python对象 发现 name被删除了
View Code

总结,有一些内置函数/模块要想正确的使用它们,那么必须按照它规定的语法来实现

__len__ (self)  很常用的方法  表现方式: object.__len__()

返回容器的长度,可变和不可变类型都需要实现。

class Ruler:
    def __init__(self,price,length,precision):
        self.price = price
        self.length = length
        self.precision = precision
    def __len__(self):
        return self.length
ruler = Ruler(3,20,0.1)
print(len(ruler))  #调用__len__方法后拿到长度  20
View Code

比较操作符系列  返回bool值

__cmp__(self,other)

__cmp__ 是所有比较魔法方法中最基础的一个,它实际上定义了所有比较操作符的行为(<,==,!=,等等),但是它可能不能按照你需要的方式工作(例如,判断一个实例和另一个实例是否相等采用一套标准,而与判断一个实例是否大于另一实例采用另一套)。 __cmp__ 应该在 self < other 时返回一个负整数,在 self == other 时返回False,在 self > other 时返回正整数。最好只定义你所需要的比较形式,而不是一次定义全部。 如果你需要实现所有的比较形式,而且它们的判断标准类似,那么 __cmp__ 是一个很好的方法,可以减少代码重复,让代码更简洁

  • __eq__(self,other) 定义等于操作符 == 的行为    

class Scientist:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        if self.name == other.name and self.age == other.name:
            return True
        return False
name1 = Scientist('Sheldon',29)
name2 = Scientist('Sheldon',29)

# print(name1 == name2)
# print(name1 is name2)
print(name1.__eq__(name2))   #这三种方法输出都False, name1 和name2 实例化后得到的内存地址不同,所以并不相同
View Code
  • __ne__(self,other) 定义不等于 != 行为

  • __lt__(self,other)  定义小于  <   行为

  • __gt__(self,other) 定义大于 >   行为

  • __le__(self,other) 定于小于等于 <= 行为

  • __ge__(self,other) 定于大于等于 >= 行为

 

 

 

 

 

 

 

 

 

 

 

 

...

转载于:https://www.cnblogs.com/CrazySheldon1/p/10029886.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值