python经常使用函数进阶(1)

在今天的QRNN替代LSTM的过程当中, 为了可以将代码改写成Tacotron2中模块类的形式,以便于将QRNN嵌入进现有代码, 学习了几种python函数和进阶用法:

  1. __call__() 函数
  2. lambda 函数
  3. np.random.randint() 函数
  4. @property



1. __call__() 函数

首先直接看代一组代码:python

class test1():
    def __init__(self, a):
        self.a = a
    def __call__(self, b):
        self.b = b
        print(self.b)
        return (self.a + self.b)

n1 = test1(1)
print(hasattr(n1, '__call__'))
>>>True

class test2():
    def __init__(self, a):
        self.a = a

n2 = test2(2)
print(hasattr(n2, '__call__'))
>>>False

上面代码中定义了两个类,分别是test1类和test2类,不一样的是,test1类中多定义了一个__call__()函数。分别实例化这两个类,而后采用hasattr()函数查看两个实例对象,就能够总结出如下__call__()函数的做用:
__call__()函数,或者在python中称之为方法,其做用在于给类的实例提供可调用的接口,即除了类自己是个可调用对象以外,类的实例也是一个可调用对象。
上面说明书式的定义很差理解,以例子为说明:dom

n1 = test1(1)
value = n1(2)
print(value)
>>>3

上面代码中n1是类test1的一个实例化对象,有了__call__()函数,就能够像初始化类的实例那样,写出第二行那样的代码。更为通俗的说,就是咱们实际想要写的操做函数,均可以放到__call__()函数的内部中进行,这样就可让类的实例做为普通python函数那样使用。实际上,就能够理解成是一种()运算符的重载。函数


2. lambda 函数

g = lambda x:x+1    # (1)

def g(x):           # (2)
    return x+1

上面代码(1)彻底等同于(2),代码精简,实际效率不会有改变学习


3. np.random.randint() 函数

import numpy as np

# np.random.randint(low, high, size)

np.random.randint(1,3,size = [1,3])
>>>[[1],[2],[2]]

该函数产生[low, high)之间的随机整数,格式为指定size的shapecode


4. @property

# 原始版本
class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

# 普通添加限制版本
class Celsius:
    def __init__(self, temperature = 0):
        self.set_temperature(temperature)

    def to_fahrenheit(self):
        return (self.get_temperature() * 1.8) + 32

    # new update
    def get_temperature(self):
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        self._temperature = value

# property版本
class Celsius:
    def __init__(self, temperature = 0):
        self._temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    @property
    def temperature(self):
        print("Getting value")
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

@property的产生来源于现实须要,原始版本的Celsius在建立实例时,没法给出温度的限制区间。若是直接经过添加get()函数和set()函数的方法来设定限制,那么在访问实例的属性的时候,代码已经变成没法向后兼容了。所以,为了兼顾向后兼容性和设定限制,@property应运而生。
实际上,观察@property的代码,能够发现温度已经从公有属性,变成私有属性,也就是说,为了向后兼容性,@property提供了访问私有属性的接口。对象

Tips : An underscore (_) at the beginning is used to denote private variables in Python.
python中用前置下划线表明私有变量接口

相关文章
相关标签/搜索