Todos os produtos
Search
Central de documentação

MaxCompute:Desenvolver uma UDF em Python 2

Última atualização: Aug 21, 2026

O MaxCompute utiliza a versão Python 2.7. Este tópico descreve como escrever uma função definida pelo usuário (UDF) em Python 2.

Estrutura do código da UDF

Use o MaxCompute Studio para escrever o código da UDF em Python 2. O código pode conter os seguintes elementos:

  • Declaração de codificação: opcional.

    O formato da declaração é #coding:utf-8 ou # -*- coding: utf-8 -*-. Ambos os formatos são equivalentes. Se o código da UDF em Python 2 contiver caracteres chineses, a execução retornará um erro. Para resolver esse problema, adicione uma declaração de codificação no cabeçalho do código.

  • Importação de módulo: obrigatória.

    O código da UDF deve incluir from odps.udf import annotate para importar a assinatura da função. Isso permite que o MaxCompute identifique a assinatura definida no código. Para referenciar arquivos ou tabelas no código da UDF, inclua from odps.distcache import get_cache_file ou from odps.distcache import get_cache_table.

  • Assinatura da função: obrigatória.

    A assinatura da função segue o formato @annotate(<signature>). O parâmetro signature define os tipos de dados dos parâmetros de entrada e do valor de retorno da UDF. Para mais informações sobre assinaturas de função, consulte Function signatures and data types.

  • Classe Python personalizada: obrigatória.

    A classe Python personalizada é a unidade organizacional do código da UDF. Essa classe define as variáveis e os métodos necessários para atender aos requisitos de negócios. No código da UDF, também é possível referenciar bibliotecas de terceiros instaladas no MaxCompute, além de arquivos ou tabelas. Para mais detalhes, consulte Third-party libraries ou Reference resources.

  • Método evaluate: obrigatório.

    O método evaluate reside na classe Python personalizada. O método evaluate define os parâmetros de entrada e o valor de retorno da UDF. Cada classe Python pode conter apenas um método evaluate.

Código de exemplo:

#coding:utf-8
# Import the function signature. 
from odps.udf import annotate
# The function signature. 
@annotate("bigint,bigint->bigint")
# The custom Python class. 
class MyPlus(object):
# The evaluate method. 
   def evaluate(self, arg0, arg1):
       if None in (arg0, arg1):
           return None
       return arg0 + arg1

Limites

O MaxCompute permite escrever UDFs Python 2 na versão 2.7 e executar o código em um ambiente sandbox. Nesse ambiente, as seguintes operações são proibidas:

  • Ler e gravar dados em arquivos locais.

  • Iniciar subprocessos.

  • Iniciar threads.

  • Ativar comunicação por socket.

  • Usar outros sistemas para chamar UDFs Python 2.

Devido a esses limites, escreva o código enviado com bibliotecas padrão do Python. Se módulos ou módulos de extensão C das bibliotecas padrão envolverem as operações mencionadas acima, não será possível utilizá-los. Observe os seguintes pontos sobre os módulos das bibliotecas padrão do Python:

  • Todos os módulos implementados com base nas bibliotecas padrão do Python que não dependem de módulos de extensão estão disponíveis.

  • Os seguintes módulos de extensão C estão disponíveis:

    • array e audioop

    • binascii e bisect

    • cmath, _codecs_cn, _codecs_hk, _codecs_iso2022, _codecs_jp, _codecs_kr, _codecs_tw, _collections e cStringIO

    • datetime

    • _functools e future_builtins

    • _heapq e _hashlib

    • itertools

    • _json

    • _locale e _lsprof

    • math, _md5 e _multibytecodec

    • operator

    • _random

    • _sha256, _sha512, _sha, _struct e strop

    • time

    • unicodedata

    • _weakref

    • cPickle

  • Ao executar o código da UDF em um ambiente sandbox, o tamanho máximo de dados graváveis na saída padrão (sys.stdout) ou na saída de erro padrão (sys.stderr) é de 20 KB. Se o tamanho exceder 20 KB, o sistema ignorará os caracteres extras.

Bibliotecas de terceiros

Bibliotecas de terceiros, como NumPy, estão instaladas no ambiente Python 2 do MaxCompute como complemento às bibliotecas padrão.

Nota

O uso de bibliotecas de terceiros está sujeito a alguns limites. Por exemplo, ao usar uma biblioteca de terceiros, não é permitido acessar dados locais e apenas recursos limitados de I/O de rede podem ser utilizados. As APIs relacionadas nessas bibliotecas ficam desativadas.

Assinaturas de função e tipos de dados

Formato das assinaturas de função:

@annotate(<signature>)

O parâmetro signature é uma string que especifica os tipos de dados dos parâmetros de entrada e do valor de retorno. Ao executar uma UDF, os tipos de dados dos parâmetros de entrada e do valor de retorno devem corresponder aos tipos especificados na assinatura da função. A análise semântica verifica a consistência dos tipos de dados. Se houver inconsistência, o sistema retornará um erro. Formato de uma assinatura:

'arg_type_list -> type'

Descrição dos parâmetros:

  • arg_type_list: especifica os tipos de dados dos parâmetros de entrada. Se houver múltiplos parâmetros de entrada, separe seus tipos de dados por vírgulas (,). Os seguintes tipos de dados são suportados: BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR e VARCHAR. Tipos de dados complexos, como ARRAY, MAP e STRUCT, bem como tipos complexos aninhados, também são suportados.

    arg_type_list pode ser representado por um asterisco (*) ou deixado vazio ('').

    • Se arg_type_list for representado por um asterisco (*), um número variável de parâmetros de entrada será permitido.

    • Se arg_type_list for deixado vazio (''), nenhum parâmetro de entrada será usado.

  • type: especifica o tipo de dados do valor de retorno. Uma UDF retorna apenas uma coluna de valores. Os seguintes tipos de dados são suportados: BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE e DECIMAL(precision,scale). Tipos de dados complexos, como ARRAY, MAP e STRUCT, bem como tipos complexos aninhados, também são suportados.

Nota

Ao escrever o código da UDF, selecione um tipo de dados com base na edição de tipos de dados do MaxCompute utilizada pelo seu projeto. Para mais informações sobre as edições de tipos de dados do MaxCompute e os tipos suportados em cada edição, consulte Data type editions.

A tabela a seguir fornece exemplos de assinaturas de função válidas.

Assinatura da função

Descrição

'bigint,double->string'

Os tipos de dados dos parâmetros de entrada são BIGINT e DOUBLE, e o tipo de dados do valor de retorno é STRING.

'*->string'

Um número variável de parâmetros de entrada é utilizado e o tipo de dados do valor de retorno é STRING.

'->double'

Nenhum parâmetro de entrada é utilizado e o tipo de dados do valor de retorno é DOUBLE.

'array<bigint>->struct<x:string, y:int>'

O tipo de dados dos parâmetros de entrada é ARRAY<BIGINT> e o tipo de dados do valor de retorno é STRUCT<x:STRING, y:INT>.

'->map<bigint, string>'

Nenhum parâmetro de entrada é utilizado e o tipo de dados do valor de retorno é MAP<BIGINT, STRING>.

A tabela a seguir descreve os mapeamentos entre os tipos de dados suportados no MaxCompute SQL e os tipos de dados do Python 2. Escreva as UDFs Python com base nesses mapeamentos para garantir a consistência dos tipos de dados.

Tipo de dados do MaxCompute SQL

Tipo de dados do Python 2

BIGINT

INT

STRING

STR

DOUBLE

FLOAT

BOOLEAN

BOOL

DATETIME

INT

FLOAT

FLOAT

CHAR

STR

VARCHAR

STR

BINARY

BYTEARRAY

DATE

INT

DECIMAL

DECIMAL.DECIMAL

ARRAY

LIST

MAP

DICT

STRUCT

COLLECTIONS.NAMEDTUPLE

Nota
  • O tipo DATETIME suportado no MaxCompute SQL é mapeado para o tipo de dados INT do Python. Um valor do tipo INT segue o formato UNIX, que corresponde ao número de milissegundos decorridos desde 00:00:00 de quinta-feira, 1º de janeiro de 1970. Processe dados do tipo DATETIME usando o módulo DATETIME nas bibliotecas padrão do Python.

  • O parâmetro silent foi adicionado a odps.udf.int(value). Se o parâmetro silent estiver definido como True e o tipo de dados de value não puder ser convertido para o tipo INT, None será retornado sem gerar erro.

  • NULL no MaxCompute SQL é mapeado para None no Python 2.

Referenciar recursos

Referencie arquivos ou tabelas no código da UDF Python 2 usando o módulo odps.distcache.

  • odps.distcache.get_cache_file(resource_name): retorna o conteúdo de um arquivo especificado.

    • resource_name é uma string que especifica o nome de um arquivo existente no seu projeto MaxCompute. Se o nome do arquivo for inválido ou se o arquivo não existir, um erro será retornado.

      Nota

      Para referenciar um arquivo no código da UDF, declare-o ao criar a UDF. Caso contrário, um erro será retornado ao chamar a UDF.

    • O valor de retorno é um objeto semelhante a um arquivo. Se esse objeto não for mais utilizado, chame o método close para liberar o arquivo aberto.

    O código a seguir mostra como referenciar um arquivo.

    from odps.udf import annotate
    from odps.distcache import get_cache_file
    @annotate('bigint->string')
    class DistCacheExample(object):
    def __init__(self):
        cache_file = get_cache_file('test_distcache.txt')
        kv = {}
        for line in cache_file:
            line = line.strip()
            if not line:
                continue
            k, v = line.split()
            kv[int(k)] = v
        cache_file.close()
        self.kv = kv
    def evaluate(self, arg):
        return self.kv.get(arg)
  • odps.distcache.get_cache_table(resource_name): retorna o conteúdo de uma tabela especificada.

    • resource_name é uma string que especifica o nome de uma tabela existente no seu projeto MaxCompute. Se o nome da tabela for inválido ou se a tabela não existir, um erro será retornado.

    • O valor de retorno é do tipo de dados GENERATOR. O chamador percorre a tabela para obter seu conteúdo. Um registro do tipo ARRAY é obtido a cada iteração.

    O código a seguir mostra como referenciar uma tabela.

    from odps.udf import annotate
    from odps.distcache import get_cache_table
    @annotate('->string')
    class DistCacheTableExample(object):
        def __init__(self):
            self.records = list(get_cache_table('udf_test'))
            self.counter = 0
            self.ln = len(self.records)
        def evaluate(self):
            if self.counter > self.ln - 1:
                return None
            ret = self.records[self.counter]
            self.counter += 1
            return str(ret)

Processo de desenvolvimento

Ao desenvolver uma UDF, faça os preparativos, escreva o código da UDF, envie o programa Python, crie a UDF, depure-a e chame-a. O MaxCompute permite usar várias ferramentas para desenvolver uma UDF, como MaxCompute Studio, DataWorks e o cliente MaxCompute (odpscmd).

  • O processo de uso de várias ferramentas para desenvolver UDFs em Python 2 é igual ao processo de desenvolvimento de UDFs em Python 3. Para mais informações sobre o processo de desenvolvimento e exemplos de como desenvolver uma UDF em Python, consulte Development process.

  • Para mais informações sobre como usar o MaxCompute Studio para desenvolver e chamar uma UDF em Python 2, consulte Develop a Python UDF.

Notas de uso

Após desenvolver uma UDF Python 2, use o MaxCompute SQL para chamá-la. Chame uma UDF Python 2 usando um dos seguintes métodos:

  • Usar uma UDF em um projeto MaxCompute: este método é semelhante ao uso de built-in functions. Utilize uma função definida pelo usuário da mesma forma que uma função integrada.

  • Usar uma UDF entre projetos: utilize uma UDF do Projeto B no Projeto A. A instrução a seguir mostra um exemplo: select B:udf_in_other_project(arg0, arg1) as res from table_t;. Para mais informações sobre compartilhamento entre projetos, consulte Cross-project resource access based on packages.