Todos os produtos
Search
Central de documentação

MaxCompute:Desenvolver uma UDF em Python 2

Última atualização: Jun 26, 2026

O MaxCompute usa o Python 2.7 para executar funções definidas pelo usuário (UDFs). Este tópico explica como escrever uma UDF em Python 2, desde a estrutura do código e as restrições de sandbox até os mapeamentos de tipos de dados e referências de recursos.

Estrutura do código da UDF

Uma UDF em Python 2 tem cinco componentes. Um é opcional ou condicional; os outros quatro são sempre obrigatórios.

Componente

Obrigatório

Finalidade

Declaração de codificação

Opcional (obrigatório se o código contiver caracteres chineses)

Declara a codificação do arquivo

Importação de módulo

Obrigatório

Importa a assinatura da função e módulos de recursos

Assinatura da função

Obrigatório

Define os tipos de dados de entrada e retorno via @annotate

Classe Python personalizada

Obrigatório

Unidade organizacional da lógica da UDF

Método evaluate

Obrigatório

Define os parâmetros de entrada e o valor de retorno da UDF; cada classe pode ter apenas um

Declaração de codificação

Adicione uma declaração de codificação no início de qualquer arquivo de UDF que contenha caracteres chineses. Sem ela, o MaxCompute retorna um erro durante a execução. Os dois formatos abaixo são equivalentes:

#coding:utf-8
# -*- coding: utf-8 -*-

Importação de módulo

Toda UDF deve importar o módulo de assinatura da função:

from odps.udf import annotate

Para referenciar arquivos ou tabelas no código da UDF, importe também de odps.distcache:

from odps.distcache import get_cache_file   # for file resources
from odps.distcache import get_cache_table  # for table resources

Assinatura da função

O decorador @annotate define os tipos de dados dos parâmetros de entrada e do valor de retorno. O MaxCompute verifica a consistência dos tipos durante a análise semântica e retorna um erro se houver incompatibilidade.

@annotate("bigint,bigint->bigint")

Para ver a sintaxe completa da assinatura, consulte Assinaturas de função e tipos de dados.

Exemplo mínimo

O exemplo a seguir mostra uma UDF completa e funcional que soma dois números inteiros. Ele abrange todos os componentes obrigatórios.

#coding:utf-8
# Import the function signature.
from odps.udf import annotate

# Define input types (BIGINT, BIGINT) and return type (BIGINT).
@annotate("bigint,bigint->bigint")
class MyPlus(object):
    def evaluate(self, arg0, arg1):
        if None in (arg0, arg1):
            return None
        return arg0 + arg1
Nota

Sempre trate entradas

None

explicitamente. Valores NULL no MaxCompute SQL correspondem a

None

no Python 2. Portanto, não verificar a presença de

None

pode causar erros inesperados.

Limitações

Operações proibidas

O MaxCompute executa o código de UDFs em Python 2 dentro de uma sandbox. As seguintes operações não são permitidas:

  • Leitura ou gravação em arquivos locais

  • Início de subprocessos

  • Início de threads

  • Abertura de conexões de socket

  • Chamada de UDFs em Python 2 a partir de sistemas externos

Devido a essas restrições, todo o código enviado deve usar apenas as bibliotecas padrão do Python. Não é possível usar módulos ou módulos de extensão C que executem as operações proibidas listadas acima.

Módulos disponíveis na biblioteca padrão

Todos os módulos escritos puramente em Python da biblioteca padrão (aqueles sem dependência de módulos de extensão C) estão disponíveis.

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

  • array, audioop

  • binascii, bisect

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

  • datetime

  • _functools, future_builtins

  • _heapq, _hashlib

  • itertools

  • _json

  • _locale, _lsprof

  • math, _md5, _multibytecodec

  • operator

  • _random

  • _sha256, _sha512, _sha, _struct, strop

  • time

  • unicodedata

  • _weakref

  • cPickle

Nota

O tamanho máximo de dados graváveis em

sys.stdout

ou

sys.stderr

é de 20 KB. Qualquer saída que exceda esse limite é descartada silenciosamente.

Bibliotecas de terceiros

Bibliotecas de terceiros, como NumPy, vêm pré-instaladas no ambiente Python 2 do MaxCompute como complemento à biblioteca padrão.

Nota

O uso de bibliotecas de terceiros está sujeito às mesmas restrições de sandbox. O acesso a dados locais não é permitido e a E/S de rede é limitada. As APIs relacionadas nas bibliotecas afetadas ficam desabilitadas.

Assinaturas de função e tipos de dados

Formato da assinatura

@annotate('<arg_type_list>-><return_type>')

arg_type_list especifica os tipos dos parâmetros de entrada, separados por vírgulas. Aceita duas formas especiais:

  • * — aceita qualquer número de parâmetros de entrada

  • '' (string vazia) — não aceita parâmetros de entrada

return_type especifica o tipo do único valor de retorno.

Tipos de entrada e retorno compatíveis: BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR e os tipos complexos ARRAY, MAP, STRUCT (incluindo tipos complexos aninhados).

Nota

Os tipos de dados disponíveis nas assinaturas de função dependem da edição de tipos de dados do MaxCompute usada pelo seu projeto. Para mais detalhes, consulte

Edições de tipos de dados

.

Exemplos de assinatura

Assinatura

Descrição

'bigint,double->string'

Recebe entradas BIGINT e DOUBLE; retorna STRING

'*->string'

Recebe qualquer número de entradas; retorna STRING

'->double'

Não recebe entradas; retorna DOUBLE

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

Recebe ARRAY\; retorna STRUCT\

'->map<bigint, string>'

Não recebe entradas; retorna MAP\

Mapeamento de tipos de dados

Escreva a lógica da UDF em Python usando os tipos do Python 2 correspondentes aos tipos do MaxCompute SQL. Incompatibilidades de tipo causam erros de execução.

Tipo do MaxCompute SQL

Tipo do Python 2

Observações

BIGINT

int

STRING

str

DOUBLE

float

BOOLEAN

bool

DATETIME

int

Armazenado como milissegundos desde 00:00:00 de quinta-feira, 1º de janeiro de 1970 (Unix epoch). Use o módulo datetime para trabalhar com esses valores.

FLOAT

float

CHAR

str

VARCHAR

str

BINARY

bytearray

DATE

int

DECIMAL

decimal.Decimal

ARRAY

list

MAP

dict

STRUCT

collections.namedtuple

Observações adicionais:

  • NULL no MaxCompute SQL corresponde a None no Python 2.

  • O parâmetro silent foi adicionado a odps.udf.int(value). Se silent estiver definido como True e o valor não puder ser convertido para int, a função retornará None em vez de gerar um erro.

Referenciar recursos

Use o módulo odps.distcache para carregar recursos de arquivo ou tabela no código da UDF durante a inicialização.

Referenciar um arquivo

get_cache_file(resource_name) retorna um objeto semelhante a um arquivo com o conteúdo do recurso de arquivo especificado.

  • resource_name deve ser o nome de um recurso de arquivo existente no seu projeto MaxCompute. Se o nome for inválido ou o arquivo não existir, o sistema retornará um erro.

  • Declare o recurso de arquivo ao criar a UDF. Caso contrário, a chamada da UDF retornará um erro.

  • Chame close() no objeto retornado após concluir o uso.

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)

Referenciar uma tabela

get_cache_table(resource_name) retorna um gerador. Cada iteração produz um registro na forma de lista.

  • resource_name deve ser o nome de um recurso de tabela existente no seu projeto MaxCompute. Se o nome for inválido ou a tabela não existir, o sistema retornará um erro.

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

O processo de desenvolvimento de UDFs em Python 2 — incluindo configuração, escrita de código, upload do programa Python, criação da UDF, depuração e chamada — é idêntico ao das UDFs em Python 3.

Ferramentas de desenvolvimento compatíveis:

  • MaxCompute Studio

  • DataWorks

  • Cliente MaxCompute (odpscmd)

Chamar uma UDF em Python 2

Após desenvolver uma UDF em Python 2, chame-a a partir do MaxCompute SQL usando uma das seguintes abordagens: