彩虹然

rainbow-ran

Python3.7之内置函数与魔法方法

一、内置函数(内建函数)built-in functions与魔法方法(特殊方法)magic method(special method)的区别

内置函数(内建函数)

内建函数(内建是相对于导入import来说的)是指python内部自带的函数,不需要导入外部包即可实现的函数,比如 len(),abs()等。

Python针对众多的类型,提供了众多的内建函数来处理,这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Python常将其设置为该种类型的方法(method)。

Python内置函数列表可参考:

https://docs.python.org/3.6/library/functions.html#

魔法方法(特殊方法)

此类方法实质就是内建函数的底层函数,也即 len()函数调用的是__len__()函数等等。

由于内置函数调用特殊函数是由解释器自动调用,比如 > 操作直接调用 gt() 特殊函数,看起来比较魔法,故也称特殊函数也为魔法函数。

二、常用内置函数

以下是Python3版本所有的内置函数:

部分内置函数详解:https://www.cnblogs.com/rainbow-ran/p/12201851.html

关于类的常用内置函数

1.反射

hasattr()函数

hasattr()函数用于判断对象是否包含对应的属性。

语法:hasattr(object, name)

参数:object -- 对象。name -- 字符串,属性名。

返回值:如果对象有该属性返回 True,否则返回 False。

class Example:
    a = 1
    b = 2
    c = 3


print(hasattr(Example, 'a'))
print(hasattr(Example, 'b'))
print(hasattr(Example, 'd'))

'''
True
True
False
'''
getattr()函数

getattr() 函数用于返回一个对象属性值。

语法:getattr(object, name[, default])

参数:object -- 对象。name -- 字符串,对象属性。default -- 默认返回值,如果不提供该参数,在没有对应属

性时,将触发 AttributeError。

返回值:返回对象属性值。

print(getattr(Example, 'a'))  # 获取属性a的值
print(getattr(Example, 'd', None))
print(getattr(Example, 'd'))
'''
1
None
Traceback (most recent call last):
 ……
AttributeError: type object 'Example' has no attribute 'd'
'''

获取对象属性后返回值可直接使用:

class A:
    def set(self, a, b):
        x = a
        a = b
        b = x
        print(a, b)


A1 = A()
c = getattr(A1, 'set')
c(1, 2)
'''
2 1
'''
setattr()函数

setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的。

语法:setattr(object, name, value)

参数:object -- 对象。name -- 字符串,对象属性。value -- 属性值。

返回值:无。

对已存在的属性进行赋值

class Example:
    a = 1
    b = 2
    c = 3


print(getattr(Example, 'c'))
setattr(Example, 'c', 4)
print(Example.c)

如果属性不存在会创建一个新的对象属性,并对属性赋值:

print(getattr(Example, 'd', None))
setattr(Example, 'd', 10)
print(Example.d)

'''
None
10
'''
delattr()函数

描述:delattr 函数用于删除属性。delattr(x, 'foobar') 相等于 del x.foobar。

语法:delattr(object, name)

参数:object -- 对象。name -- 必须是对象的属性。

返回值:无。

class Coordinate:
    x = 10
    y = -5
    z = 0


point1 = Coordinate()

print('x = ', point1.x)
print('y = ', point1.y)
print('z = ', point1.z)

delattr(Coordinate, 'z')

print('--删除 z 属性后--')
print('x = ', point1.x)
print('y = ', point1.y)

# 触发错误
print('z = ', point1.z)
'''
x =  10
y =  -5
z =  0
--删除 z 属性后--
x =  10
y =  -5
'''

2.isinstance()函数

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

语法:isinstance(object, classinfo)

参数:object -- 实例对象。classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。

对于基本类型来说 classinfo 可以是:int,float,bool,complex,str(字符串),list,dict(字典),set,tuple

返回值:如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。

a = 2
print(isinstance(a, int))
print(isinstance(a, str))
print(isinstance(a, (str, int, list)))  # 是元组中的一个返回True

'''
True
False
True
'''

type()与isinstance()的区别

class A:
    pass


class B(A):
    pass


print(isinstance(B(), A))
print(type(B()) == A)

'''
True
False
'''

3.issubclass()函数

描述:issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类。

语法:issubclass(class, classinfo)

参数:class -- 类。classinfo -- 类。

返回值:如果 class 是 classinfo 的子类返回 True,否则返回 False。

print(issubclass(B, A))

'''
True
'''

三、常用的魔法方法

构造和初始化

__init__我们很熟悉了,它在对象初始化的时候调用,我们一般将它理解为"构造函数"。

实际上, 当我们调用x = SomeClass()的时候调用,__init__并不是第一个执行的, __new__才是。所以准确来说,是__new____init__共同构成了"构造函数"。

__new__是用来创建类并返回这个类的实例, 而__init__只是将传入的参数来初始化该实例。

__new__在创建一个实例的过程中必定会被调用,但__init__就不一定,比如通过pickle.load的方式反序列化一个实例时就不会调用__init__

__new__方法总是需要返回该类的一个实例,而__init__不能返回除了None的任何值。比如下面例子:

classFoo(object):

    def__init__(self):
        print 'foo __init__'
        return None  # 必须返回None,否则抛TypeError

    def__del__(self):
        print 'foo __del__'

实际中,你很少会用到__new__,除非你希望能够控制类的创建。
如果要讲解__new__,往往需要牵扯到metaclass(元类)的介绍。

对于__new__的重载,Python文档中也有了详细的介绍。

在对象的生命周期结束时, __del__会被调用,可以将__del__理解为"析构函数".
__del__定义的是当一个对象进行垃圾回收时候的行为。

有一点容易被人误解, 实际上,x.__del__() 并不是对于del x的实现,但是往往执行del x时会调用x.__del__().

怎么来理解这句话呢? 继续用上面的Foo类的代码为例:

foo = Foo()
foo.__del__()
print foo
del foo
print foo  # NameError, foo is not defined

class Testclass:
def new(cls, *args, **kwargs):
print("创建实例")
return object.new(cls)

class Testclass:
    def __new__(cls, *args, **kwargs):
        print("创建实例")
        return object.__new__(cls)

    def __init__(self):
        print("初始化实例")
    def __del__(self):
        print("销毁")
        print("自动调用del")

Testclass()
‘’‘
创建实例
初始化实例
销毁
自动调用del
’‘’

如果调用了foo.__del__(),对象本身仍然存在. 但是调用了del foo, 就再也没有foo这个对象了.

请注意,如果解释器退出的时候对象还存在,就不能保证 __del__ 被确切的执行了。所以__del__并不能替代良好的编程习惯。
比如,在处理socket时,及时关闭结束的连接。

__str____repr__

当被 str() 调用时会执行__str__。此方法类似JAVA中的toString方法。

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

class B:
    def __init__(self,name):
        self.name = name
    def __str__(self):#重写__str__方法
        return self.name

a = A("Tom")
print(a)
b = B("Jake")
print(b)

'''
<__main__.A object at 0x105844690>
Jake
'''

__repr____str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员。

打印操作会首先尝试__str__和str内置函数(print运行的内部等价形式),它通常应该返回一个友好的显示。

__repr__用于所有其他的环境中:用于交互模式下提示回应以及repr函数,如果没有使用__str__,会使用print和str。它通常应该返回一个编码字符串,可以用来重新创建对象,或者给开发者详细的显示。

当我们想所有环境下都统一显示的话,可以重构__repr__方法;当我们想在不同环境下支持不同的显示,例如终端用户显示使用__str__,而程序员在开发期间则使用底层的__repr__来显示,实际上__str__只是覆盖了__repr__以得到更友好的用户显示。

其他魔法方法详细总结

https://www.cnblogs.com/zhouyixian/p/11129347.html#_label0

posted @ 2020-01-17 11:48  彩虹然  阅读(878)  评论(0编辑  收藏  举报