{"record":{"id":"26cf03749cf2c26b","repo":"d2l-ai/d2l-zh","slug":"notimplementederror-26cf03","errorCode":null,"errorMessage":"NotImplementedError","messagePattern":"NotImplementedError","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"d2l/tensorflow.py","lineNumber":881,"sourceCode":"    text = preprocess_nmt(read_data_nmt())\n    source, target = tokenize_nmt(text, num_examples)\n    src_vocab = d2l.Vocab(source, min_freq=2,\n                          reserved_tokens=['<pad>', '<bos>', '<eos>'])\n    tgt_vocab = d2l.Vocab(target, min_freq=2,\n                          reserved_tokens=['<pad>', '<bos>', '<eos>'])\n    src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)\n    tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)\n    data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)\n    data_iter = d2l.load_array(data_arrays, batch_size)\n    return data_iter, src_vocab, tgt_vocab\n\nclass Encoder(tf.keras.layers.Layer):\n    \"\"\"编码器-解码器架构的基本编码器接口\"\"\"\n    def __init__(self, **kwargs):\n        super(Encoder, self).__init__(**kwargs)\n\n    def call(self, X, *args, **kwargs):\n        raise NotImplementedError\n\nclass Decoder(tf.keras.layers.Layer):\n    \"\"\"编码器-解码器架构的基本解码器接口\n\n    Defined in :numref:`sec_encoder-decoder`\"\"\"\n    def __init__(self, **kwargs):\n        super(Decoder, self).__init__(**kwargs)\n\n    def init_state(self, enc_outputs, *args):\n        raise NotImplementedError\n\n    def call(self, X, state, **kwargs):\n        raise NotImplementedError\n\nclass EncoderDecoder(tf.keras.Model):\n    \"\"\"编码器-解码器架构的基类\n\n    Defined in :numref:`sec_encoder-decoder`\"\"\"","sourceCodeStart":863,"sourceCodeEnd":899,"githubUrl":"https://github.com/d2l-ai/d2l-zh/blob/e6b18ccea71451a55fcd861d7b96fddf2587b09a/d2l/tensorflow.py#L863-L899","documentation":"A NotImplementedError raised by d2l.tensorflow.Encoder.call. Encoder is the abstract interface of the encoder-decoder architecture (sec_encoder-decoder): it is a tf.keras.layers.Layer whose call is intentionally left unimplemented. Subclasses (Seq2SeqEncoder, TransformerEncoder, ...) must override call; instantiating the base class and invoking it as a layer triggers the error.","triggerScenarios":"Instantiating d2l.Encoder() directly and calling encoder(X); a custom encoder subclass whose forward method is misspelled (e.g. 'forward' instead of 'call' in the TF API) so the base call runs; type-testing code that calls call on an arbitrary Encoder instance.","commonSituations":"Porting PyTorch d2l code to TensorFlow: writing def forward(self, X) on a TF subclass silently falls through to the base call; omitting the override entirely while developing a new architecture chapter; IDE auto-generating __init__ but not call.","solutions":["Subclass and override call: class MyEncoder(d2l.Encoder): def call(self, X, *args, **kwargs): ...","If porting from the PyTorch edition, rename forward -> call in TensorFlow subclasses.","Use the provided concrete implementations, e.g. d2l.Seq2SeqEncoder(vocab_size, num_hiddens, num_layers, dropout), instead of the abstract base.","Check for typos in the method name (call vs calls) and correct signature (self, X, *args, **kwargs)."],"exampleFix":"# before\nenc = d2l.Encoder()\nenc(X)  # NotImplementedError\n# after\nclass MyEncoder(d2l.Encoder):\n    def call(self, X, *args, **kwargs):\n        return tf.identity(X)\nenc = MyEncoder()\nenc(X)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_concrete_encoder(enc) -> bool:\n    return (isinstance(enc, d2l.Encoder)\n            and type(enc).call is not d2l.Encoder.call)","tryCatchPattern":"try:\n    enc(X)\nexcept NotImplementedError:\n    raise TypeError(f'{type(enc).__name__} must override Encoder.call(X, *args, **kwargs)') from None","preventionTips":["In TensorFlow subclasses, the method must be named call (not forward).","Prefer library encoders (d2l.Seq2SeqEncoder) unless writing a custom architecture.","Add a smoke test that runs one forward pass on a tiny batch right after constructing any new encoder."],"tags":["d2l","tensorflow","encoder-decoder","abstract-class","notimplementederror"],"backgroundTag":null,"analyzedSha":"e6b18ccea71451a55fcd861d7b96fddf2587b09a","analyzedAt":"2026-08-14T20:05:26.414Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}