Python的__new__、__init__、__call__方法

前言
  当我们自定义类时,常见的情况是,只定义了__init__方法对进行类实例初始化的工作,似乎不涉及其他语言比如Java中常说的“需要对象就new一个”的操作,但Python的 新式类 中也有__new__方法,还有__call__方法的概念。

三类方法介绍

1、__init__方法(初始化方法)

  init 是 initialization(初始化)的缩写,__init__方法是类的一个特殊的固有方法,通常称为 初始化方法,用于初始化对象,定义并初始化对象的属性,即给属性赋值 。格式形如:

def __init__(self, arg1, arg2, ..., argn):
	self.arg1 = arg1
	self.arg2 = arg2
	...
	self.argn = argn

  __init__ 方法的第一个参数是self( self 通常由 __new__ 方法返回),指代当前实例,而不一定是该类的实例;arg1, arg2, …, argn为形参,在实例化时需传递对应的实参,一般用于初始化实例属性。

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

if __name__ == '__main__':
	obj = Demo('sidian', 18)   # 创建Demo的实例obj,初始化name为'sidian',age为18
	print(obj.name)
	print(obj.age)

# 输出
# sidian
# 18

2. __new__方法 (构造方法)

  __new__方法就是 创建实例的静态方法,在类准备实例化时调用,其作用是为实例对象分配内存空间、返回对象的引用传递给 __init__ 方法的 self 参数,因此调用顺序优先于 __init__ 初始化方法。
  在自定义新式类时,__new__方法可定义可不定义,当没有重新定义__new__()时,Python默认调用该类直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写__new__(),那么将一直向上追溯父类的__new__()方法直至object类(所有新式类的基类)的__new__()方法。

在基类object中默认的__new__方法已经封装了创建对象、为对象分配空间的动作。
object类中__new__方法源代码如下:

    @staticmethod # known case of __new__
    def __new__(cls, *more): # known special case of object.__new__
     """ Create and return a new object.  See help(type) for accurate signature. """
     pass

  当在类中重写__new__方法时,无论有没有被加上@staticmethod装饰器,它始终都是类的静态方法,格式形如:

def __new__(cls, *args, **kwargs):
	...
	return 实例对象

参数:__new__方法至少要有第一个参数cls,代表当前要实例化的类,此参数在实例化时由Python解释器自动提供;位置参数和关键字参数用于接收实例化时输入的实参。
返回值:__new__方法还必须要有返回值,返回一个实例化对象(通常会返回该类的实例,但也可能返回其他类的实例),然后传入被返回实例对象所在类的__init__初始化方法的第一个参数。

验证

class Cir():
   def __new__(cls, *args, **kwargs):
       # 看看Python传递给__new__的参数
       print("Python传递给__new__的参数:\ncls: ", cls, "\nargs: ", args, "\nkwargs:", kwargs)
       inst = super().__new__(cls)
       print("__new__返回值:", inst)
       return inst

   def __init__(self, radius, size):
       print("\nPython传递给_init__的参数:\nself的值为:", self, "\nradius的值为:", radius, "\nsize的值为:", size)
       self.radius = radius


cir = Cir(10, size=8)

运行结果:

Python传递给__new__的参数:
cls:  <class '__main__.Cir'> 
args:  (10,) 
kwargs: {'size': 8}
__new__返回值: <__main__.Cir object at 0x0000021411631EB0>

Python传递给_init__的参数:
self的值为: <__main__.Cir object at 0x0000021411631EB0> 
radius的值为: 10 
size的值为: 8

  可以看到,__new__方法中调用父类__new__方法返回的实例 inst 与__init__方法的 self 指向同一个内存地址;位置参数和关键字参数接收创建实例传入的所有位置参数和关键字参数。

2.1 __new__方法必须要返回实例

  如下例,自定义类B,只定义__init__方法,对B进行实例化,观察结果:

class B(object):
	def __init__(self):
		print("__init__被执行了!")

b = B()
print(b)

# 执行结果:
# __init__被执行了!
# <__main__.B object at 0x0000025AAE3CD730>

  对类B加上没有任何返回结果的__new__方法,再进行实例化,观察结果:

class B(object):
	def __new__(cls):
		print("__new__被执行了!")
		
	def __init__(self):
		print("__init__被执行了!")

b = B()
print(b)

# 执行结果:
# __new__被执行了!
# None

  这次执行结果没有像一开始只有__init__方法那样输出实例的内存地址,因为如上述所说,__init__ 方法的 self 形参的实参由__new__方法返回并传递——只有__init__方法的类B继承了object的__new__方法返回了实例,因此能够顺利创建并初始化实例;而有无返回实例__new__方法的类B无法传递实例,因此无法成功执行初始化__init__方法。
  如果要得到当前类的实例,则需要在当前类中的__new__方法语句中调用当前类的父类的__new__方法;如果当前类是直接继承自object,则可以直接写成return object.__new__(cls)
  将__new__方法修改为返回类B实例的方法,进行实例化,观察结果:

class B(object):
    def __new__(cls):
        print("__new__被执行了!")
        return super().__new__(cls)  # 或 object.__new__(cls)

    def __init__(self):
        print("__init__被执行了!")


b = B()
print(b)

# 执行结果:
# __new__被执行了!
# __init__被执行了!
# <__main__.B object at 0x00000262A8E6ABB0>

2.2 __new__方法不一定返回当前类实例

  通常,当前类开始实例化时,__new__方法会返回cls(cls指代当前类)的实例;该类的__init__方法作为构造方法会接收这个实例(即self)作为自己的第一个参数,再依次传入__new__方法中接收的位置参数和命名参数。如果__new__方法返回其他类的实例,那么只会调用被返回类的构造方法。 如下例:

class Foo(object):
    def __init__(self, *args, **kwargs):
        pass

    def __new__(cls, *args, **kwargs):
        return object.__new__(Stranger)

class Stranger(object):
    pass

foo = Foo()
print(type(foo))  

# 执行结果:<class ‘main.Stranger'>

2.3 __new__方法接收实例化时参数的意义

思考:由上述可知,__new__方法的固定语法参数格式为 (cls, *args, **kwargs)。其中*args, **kwargs 接收的是实例化时的参数,那么__new__方法接收这些参数的意义是什么?该方法返回值的实例对象所需,还是可用这些参数按照需求实现某些操作?

2.3.1 探索一:参数是否是返回值的实例对象所需

情况①:父类为object【留个坑】

  假设某类父类默认为object,直接用object.__new__方法返回实例对象,所有参数传入此方法中。

Python帮助文档 表明可以传多个值!如下所示:

object.__new__(cls[, …])

调用以创建一个 cls 类的新实例。__new__() 是一个静态方法 (因为是特例所以你不需要显式地声明),它会将所请求实例所属的类作为第一个参数。其余的参数会被传递给对象构造器表达式 (对类的调用)。__new__() 的返回值应为新对象实例 (通常是 cls 的实例)。

Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super().__new__(cls[, …]) with appropriate arguments and then modifying the newly created instance as necessary before returning it.

如果 __new__() 在构造对象期间被发起调用并且它返回了一个 cls 的实例,则新实例的 __init__() 方法将以 __init__(self[, …]) 的形式被发起调用,其中 self 为新实例而其余的参数与被传给对象构造器的参数相同。

如果 __new__() 未返回一个 cls 的实例,则新实例的 __init__() 方法就不会被执行。
__new__() 的目的主要是允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程。它也常会在自定义元类中被重载以便定制类创建过程。

交互模式下通过help查看此方法显示可传多个参数

>>> help(object.__new__)
Help on built-in function __new__:

__new__(*args, **kwargs) method of builtins.type instance
   Create and return a new object.  See help(type) for accurate signature.

示例探索如下:

class Cir():
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls, *args, **kwargs)

    def __init__(self, radius):
        print("\nPython传递给_init__的参数:\nself的值为:", self, "\nradius的值为:", radius)
        self.radius = radius


cir = Cir(10)

执行结果如下:
Traceback (most recent call last): TypeError: object.__new__() takes exactly one argument (the type to instantiate)

  该报错显示,object.__new__只能接收一个参数且只能接收类名,即必须固定语法格式为 object.__new__(cls)

  至于为何object.__new__方法定义可接收多个参数实际却只能接收cls,不太清楚,留个坑!

情况②:父类为自定义类

  定义两个类,Vehicle类和Car类,Car是从Vehicle派生的,Car重写了__new__方法,验证几种情况:

  1. Vehicle类没有重写__new__方法。
  2. Vehicle类重写__new__方法,该方法只接受一个参数cls。
  3. Vehicle类重写__new__方法,该方法接受所有参数。
分析
● 对于1,因为Vehicle没有重写__new__方法,最终会调用基类 object的__new__方法,执行结果与上述情况①一致,不再赘述。
● 对于2,因为Vehicle类的__new__方法只接受cls一个参数,所以定义Vehicle类的__init__方法时也只能有一个参数self而不能有其他实例变量。另外,当Car类的__new__方法需要调用父类的__new__方法传入全部参数时欲返回实例时必然行不通,只能传入参数cls进行验证。
● 对于2和3,Vehicle类的父类为 object,因此Vehicle类中的 __new__方法返回实例时只能写成super().__new__(cls)object.__new__(cls)

验证2:Vehicle类重写__new__方法,该方法只接受一个参数cls,示例如下:

class Verhicle():
    def __init__(self):
        print("__init__被执行了!")

    def __new__(cls):
        print("In Verhicle __new__,Python传递给__new__的参数:\ncls:", cls)
        inst = super().__new__(cls)
        print("__new__的返回值:", inst)
        return inst

class Car(Verhicle):
    def __init__(self, wheelcount, power, oilcostperkm):
        self.wheelcount, self.power, self.oilcostperkm = wheelcount, power, oilcostperkm
        print("__init__的实例变量:", self.wheelcount, self.power, self.oilcostperkm)

    def __new__(cls, *args, **kwargs):
        print("In Car __new__,Python传递给__new__的参数:\ncls:", cls, "\nargs:", args, "\nkwargs:", kwargs)
        inst = super().__new__(cls)
        print("__new__的返回值:", inst)
        return inst

car = Car(4, "汽车发动机", 0.1)

运行结果:

In Car __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'> 
args: (4, '汽车发动机', 0.1) 
kwargs: {}
In Verhicle __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'>
__new__的返回值: <__main__.Car object at 0x0000026098C32D60>
__new__的返回值: <__main__.Car object at 0x0000026098C32D60>
__init__的实例变量: 4 汽车发动机 0.1

  执行成功!结果表明,Vehicle类的__new__方法没有定义*args, **kwargs两类参数也能顺利返回实例,子类Car也能顺利进行实例初始化。

验证3:Vehicle类重写__new__方法,该方法接受所有参数的情况,示例如下:

class Verhicle():
    def __init__(self, wheelcount, power):
        self.wheelcount, self.power, self.totaldistance = wheelcount, power, 0

    def __new__(cls, *args, **kwargs):
        print("In Verhicle __new__,Python传递给__new__的参数:\ncls:", cls, "\nargs:", args, "\nkwargs:", kwargs)
        inst = super().__new__(cls)
        print("__new__的返回值:", inst)
        return inst

class Car(Verhicle):
    def __init__(self, wheelcount, power, oilcostperkm):
        self.oilcostperkm = oilcostperkm
        super().__init__(wheelcount, power)

    def __new__(cls, *args, **kwargs):
        print("In Car __new__,Python传递给__new__的参数:\ncls:", cls, "\nargs:", args, "\nkwargs:", kwargs)
        inst = super().__new__(cls, *args, **kwargs)
        print("__new__的返回值:", inst)
        return inst

car = Car(4, "汽车发动机", 0.1)

运行结果如下:

In Car __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'> 
args: (4, '汽车发动机', 0.1) 
kwargs: {}
In Verhicle __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'> 
args: (4, '汽车发动机', 0.1) 
kwargs: {}
__new__的返回值: <__main__.Car object at 0x0000024A15352D90>
__new__的返回值: <__main__.Car object at 0x0000024A15352D90>

  执行成功!虽然Vehicle类__new__方法可接受所有参数,但是*args, **kwargs是否就是该方法返回实例所必需的变量?另外根据Vehicle类__new__方法的定义,该方法也可只接受第一个参数cls。下面探究Car类__new__方法调用父类__new__方法时只传入cls。

class Verhicle():
    def __init__(self, wheelcount, power):
        self.wheelcount, self.power, self.totaldistance = wheelcount, power, 0

    def __new__(cls, *args, **kwargs):
        print("In Verhicle __new__,Python传递给__new__的参数:\ncls:", cls, "\nargs:", args, "\nkwargs:", kwargs)
        inst = super().__new__(cls)
        print("__new__的返回值:", inst)
        return inst

class Car(Verhicle):
    def __init__(self, wheelcount, power, oilcostperkm):
        self.oilcostperkm = oilcostperkm
        super().__init__(wheelcount, power)

    def __new__(cls, *args, **kwargs):
        print("In Car __new__,Python传递给__new__的参数:\ncls:", cls, "\nargs:", args, "\nkwargs:", kwargs)
        inst = super().__new__(cls)
        print("__new__的返回值:", inst)
        return inst

car = Car(4, "汽车发动机", 0.1)

运行结果:

In Car __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'> 
args: (4, '汽车发动机', 0.1) 
kwargs: {}
In Verhicle __new__,Python传递给__new__的参数:
cls: <class '__main__.Car'> 
args: () 
kwargs: {}
__new__的返回值: <__main__.Car object at 0x000001BA42AE2D90>
__new__的返回值: <__main__.Car object at 0x000001BA42AE2D90>

  执行成功!结果表明,即使没给Vehicle类的__new__方法传入*args, **kwargs两类参数也能顺利返回实例,子类Car也能顺利进行实例初始化。

结论:
1. 情况①和情况②均表明,子类接收实例化时参数的*args, **kwargs 不是其__new__方法调用父类__new__方法获取实例对象所必需的。
2. 情况①中表明,调用object. __ new__方法时,只能传cls参数。
3. 情况②中表明,子类调用自定义父类的__ new__方法时,可否传入所有参数,取决于父类的__ new__方法的定义。

2.3.2 探索二:可用这些参数按照需求实现某些操作

  结合上述 2.2 __new__方法不一定返回当前类实例 的特点,举例体现__new__方法接收实例化时参数的意义。

● 需求一:修改Python内置类型 int 的创建行为,只允许创建非0整数。

实现方式:由于 int 可创建整数,但其包括0且已是不可变类型,所以尝试直接通过自定义子类继承 int并附加某些判断来实现。

class nonZero(int):
    def __new__(cls,value):
        return super().__new__(cls,value) if value != 0 else None
    
    def __init__(self,skipped_value):
        print("__init__()")
        super().__init__()
        
print(type(nonZero(-12)))
print(type(nonZero(0)))

运行结果:

__init__()
<class '__main__.nonZero'>
<class 'NoneType'>

  可以看到,nonZero的__new__方法接收实例参数后,可依据实例参数所传值的合理性来控制 int 的生成。这为修改不可变类的内置类型(如 int、str、float 等)的创建行为的需求,提供了思路!

● 需求二:实例化人时,只允许传入合理的年龄值。

实现方式:通过类的__new__方法对传入实例参数进行判断,控制实例的生成。

class Person(object):
 
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __new__(cls, name, age):
        if 0 < age < 150:
            return object.__new__(cls)
            # return super(Person, cls).__new__(cls)
        else:
            return None
 
    def __str__(self):
        return '{0}({1})'.format(self.__class__.__name__, self.__dict__)
 
print(Person('Tom', 10))
print(Person('Mike', 200))

运行结果:

Person({'age': 10, 'name': 'Tom'})
None

  可以看到,200岁的初始值时不合理的,因此实例也不会被生成。

结论:需求一和需求二均体现了__new__方法接收实例化时参数的可对参数进行判断,进而生成符合需求的实例的作用。

3. __call__方法

  Python中那些能够在后面加()对象名()来调用执行的对象,被称为 可调用对象,可调用对象包括 自定义函数、Python内置函数、实例对象和实例方法等

  __call__方法是Python中一个很特殊的方法。调用 可调用对象时,既可通过 对象名(),也可通过 对象名.__call__() 来实现,两者之间的关系可理解为 对象名()对象名.__call__() 的简写。特别地,当类中定义了__call__方法, 该类的实例对象 将成为可调用对象,调用该实例对象时执行__call__方法中的代码。

__call__方法的语法格式:__call__(self[, args...]),第一个参数对对象本身。

自定义函数

  对自定义函数的调用,通常情况下是在函数名后加()来调用,也可以用__call__()方法来调用。

def test():
    print("Function test() is called")

test()
test.__call__()

运行结果:

Function test() is called
Function test() is called

Python内置函数

  与自定义函数一样,内置函数既可以通过函数名后加()来调用,也可以用__call__()方法来调用。

print(int(3))
print(int.__call__(3))

运行结果:

3
3

类的实例对象

  如果一个类中没有定义__call__()方法,那么这个类的实例对象是不可以被调用的。定义了__call__()方法后,调用该实例对象就是执行__call__()方法中的代码。

class Person(object):

    def __call__(self):
        print("Method __call__() is called")

d = Person()
d()

运行结果:

Method __call__() is called

3.1 判断是否可调用对象:callable函数

  Python callable() 函数用于检查一个对象是否是可调用的。如果返回 True,调用对象object 仍然可能调用失败;但如果返回 False,调用对象object 绝对不会成功。

语法callable(object)
参数 :对象(object)
返回值 :可调用返回 True,否则返回 False。

示例:

>>>callable(0)
False
>>> callable("school")
False
>>> def add(a, b):
... return a + b
...
>>> callable(add) # 函数返回 True
True
>>> class A: # 类
... def method(self):
... return 0
...
>>> callable(A) # 类返回 True
True
>>> a = A()
>>> callable(a) # 没有实现 __call__, 返回 False
False
>>> class B:
... def __call__(self):
... return 0
...
>>> callable(B)
True
>>> b = B()
>>> callable(b) # 实现 __call__, 返回 True
True

3.2 __call__的应用场景

3.2.1 类装饰器:将类的实例对象伪装成函数

基于类实现装饰器,就必须用到__call__方法。

class SafeAdd:
    def __init__(self, func):
        self.func = func       # func是被装饰的函数

    def __call__(self, *args, **kwargs):
        if len(args) == 2:
            left = args[0]
            right = args[1]         # 获取参数并进行类型转换
            if not isinstance(left, (int, float)):
                left = float(left)

            if not isinstance(right, (int, float)):
                right = float(right)

            return left + right

        return None

if __name__ == '__main__':
	@SafeAdd
	def add(a, b):
		return a + b

	print(add(3, 5))   # 输出8
	print(add('3', '6'))  # 输出9

以上执行原理相当于

def add(a, b):
    return a + b

safe_add = SafeAdd(add)     # add函数作为参数传入SafeAdd的初始化函数__init__中
# safe_add是类SafeAdd的实例
print(safe_add(3, 5))
print(safe_add('3', '6'))

实例对象safe_add所属的类由于实现了__call__方法,因此可以像使用函数一样通过一对小括号来调用执行。

3.2.2 简化类的对象的方法调用

  当类对象某方法的调用频率很高时,则可将该方法命名为__call__来简化调用。
  定义一个制作蛋糕类以及和面、发酵、烘烤、切形状、抹奶油、摆水果、打包七个步骤的实例方法,每实例化一个类时都要依次实现这些方法,如下所示:

class MakeCake:
	#和面
	def huomian(self):
		print('和面操作')
	#发酵
	def fajiao(self):
		print('发酵操作')
	#烘烤
	def hongkao(self):
		print('烘烤操作')
	#切形状
	def qiexingzhuang(self):
		print('切形状操作')
	#抹奶油
	def monaiyou(self):
		print('抹奶油操作')
	#摆水果
	def baishuiguo(self):
		print('摆水果操作')
	#打包
	def dabao(self):
		print('打包操作')

#制作第一个蛋糕
cake1 = MakeCake()  #第一个制作蛋糕的对象
cake1.huomian()
cake1.fajiao()
cake1.hongkao()
cake1.qiexingzhuang()
cake1.monaiyou()
cake1.baishuiguo()
cake1.dabao()

#制作第二个蛋糕
cake2 = MakeCake()  #第二个制作蛋糕的对象
cake2 .huomian()
cake2 .fajiao()
cake2 .hongkao()
cake2 .qiexingzhuang()
cake2 .monaiyou()
cake2 .baishuiguo()
cake2 .dabao()

#制作第三个蛋糕
cake3 = MakeCake()  #第三个制作蛋糕的对象
...
...

  采用定义__call__方法的方式,封装这七个方法们可以大大简化制作蛋糕方法的调用。如下所示:

class MakeCake:
	#和面
	def huomian(self):
		print('和面操作')
	#发酵
	def fajiao(self):
		print('发酵操作')
	#烘烤
	def hongkao(self):
		print('烘烤操作')
	#切形状
	def qiexingzhuang(self):
		print('切形状操作')
	#抹奶油
	def monaiyou(self):
		print('抹奶油操作')
	#摆水果
	def baishuiguo(self):
		print('摆水果操作')
	#打包
	def dabao(self):
		print('打包操作')

	def __call__(self):
		self .huomian()
		self .fajiao()
		self .hongkao()
		self .qiexingzhuang()
		self .monaiyou()
		self .baishuiguo()
		self .dabao()	

cake1 = MakeCake()  #第一个制作蛋糕的对象
cake1()
cake2 = MakeCake()  #第二个制作蛋糕的对象
cake2 ()
cake3 = MakeCake()  #第三个制作蛋糕的对象
cake3 ()
3.2.3 模糊对象和函数调用时的区别 (提高代码兼容性)

  创建类A和函数B,类A下的m函数与函数B功能类似;现需将A的对象和B函数作为参数传到函数C中去执行,如下所示:

class A():
    def m(self):
        print('good')
a = A()

def B():
    print('good')

def C1(func):
    func.m()
def C2(func):
    func()

C1(a)
C2(B)

  因为对象和函数调用上的区别,所以要有两个不同的C函数才能实现相同的功能。现在通过__call__方法模糊两者的差别,提高程序的兼容性。

class A():
    def __call__(self):
        print('good')
a = A()

def B():
    print('good')

def C(func):
    func()

C(a)
C(B)

三者关系概述

  • __new__ (构造方法): 实例对象的创建,是一个静态方法,第一个参数是cls。
  • __init__ (初始化方法): 实例对象的初始化, 是一个实例方法,第一个参数是self。
  • __call__ : 对象可调用,注意不是类调用,是对象调用。

思考

  实例化一个类时,为什么总遵循先执行__new__方法,后执行__init__方法的顺序?
答疑:类实例化时先执行__new__后执行__init__的原理

参考

第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
Python中new方法的详解
Python __new__()方法详解
Python 中__new__方法详解及使用
python中的__new__方法
详解Python的__call__()方法
python面向对象 __call__方法
Python中__call__的用法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,__call__是一个特殊的方法,允许将一个对象作为函数调用。默认情况下,__call__()方法是没有实现的,这意味着大多数实例是不可调用的。但是,如果一个类定义了__call__方法,那么它的实例就可以像函数一样被调用。__call__方法可以使一个对象具有函数的行为,可以接受参数并返回结果。通过在类中定义__call__方法,可以使对象更加灵活和可用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python中__call__方法示例分析](https://download.csdn.net/download/weixin_38703968/14913063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [浅谈python中的__init__、__new__和__call__方法](https://download.csdn.net/download/weixin_38518006/12872693)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Python在大数据方面的应用前景](https://download.csdn.net/download/milk416666/88264587)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值