You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中实现类属性子切片直接调用translate方法的最佳实践

Great question! Let's walk through how to make this work in a clean, Pythonic way. First, let's fix a couple of small issues in your original code, then dive into subclassing approaches that let you call translate() directly on scores or its slices.

First: Fixes to Your Original Code

Your initial code has a couple of typos that need addressing first:

  • The build method is missing the self parameter (required for instance methods)
  • The translate method uses val in the list comprehension but references score; it should be for score in self.scores

1. Subclass list for Custom Score Container

To let scores (and its slices) have a translate() method that uses the parent Data instance's encoding, we can create a custom subclass of list that holds a reference to the parent Data object. This keeps the translation logic tightly coupled to the score data while maintaining all standard list functionality.

class ScoreList(list):
    def __init__(self, parent, iterable=()):
        super().__init__(iterable)
        self.parent = parent  # Link back to the parent Data instance
    
    def translate(self):
        # Use the parent's encoding to convert scores to strings
        return [self.parent.encoding[score] for score in self]
    
    def __getitem__(self, key):
        # Ensure slices return ScoreList instances (not regular lists) with the same parent
        result = super().__getitem__(key)
        if isinstance(result, list):
            return ScoreList(self.parent, result)
        return result

class Data:
    def __init__(self):
        self.scores = ScoreList(self)  # Initialize with parent reference
        self.encoding = {1: 'first', 2: 'second', 3:'third'}
    
    def build(self):
        # Replace scores with a populated ScoreList
        self.scores = ScoreList(self, [1,2,3])

# Test it out
d = Data()
d.build()
print(d.scores.translate())  # Output: ['first', 'second', 'third']
print(d.scores[1:].translate())  # Output: ['second', 'third']

Why This Works:

  • ScoreList inherits all standard list methods (append, extend, sort, etc.) so it behaves exactly like a normal list
  • The parent attribute ensures translate() always uses the correct encoding from the original Data instance
  • Overriding __getitem__ makes sure slices of scores also return ScoreList objects, so you can call translate() directly on slices too

2. Subclass numpy.ndarray for Array-Based Scores

If you're working with NumPy arrays instead of regular lists, you can subclass numpy.ndarray to add the translate() method. NumPy has specific rules for subclassing, so we need to handle instance creation and view preservation carefully.

import numpy as np

class ScoreArray(np.ndarray):
    def __new__(cls, input_array, parent=None):
        # Create the array instance first (required for NumPy subclasses)
        obj = np.asarray(input_array).view(cls)
        obj.parent = parent  # Attach parent reference
        return obj
    
    def __array_finalize__(self, obj):
        # Carry over the parent reference when slicing or creating views
        if obj is None:
            return
        self.parent = getattr(obj, 'parent', None)
    
    def translate(self):
        if self.parent is None:
            raise ValueError("ScoreArray must be linked to a Data instance")
        # Efficient vectorized translation for NumPy arrays
        return np.vectorize(lambda x: self.parent.encoding[x])(self)

class Data:
    def __init__(self):
        self.scores = ScoreArray([], parent=self)
        self.encoding = {1: 'first', 2: 'second', 3:'third'}
    
    def build(self):
        self.scores = ScoreArray([1,2,3], parent=self)

# Test it out
d = Data()
d.build()
print(d.scores.translate())  # Output: ['first' 'second' 'third']
print(d.scores[1:].translate())  # Output: ['second' 'third']

Why This Works:

  • __new__ and __array_finalize__ follow NumPy's subclassing rules to ensure parent references are preserved across slices and views
  • np.vectorize applies the translation logic efficiently to the entire array

Pythonic Best Practices
  • Prioritize Subclassing Over Monkey Patching: Modifying built-in types (like adding translate() to list globally) is messy and can break other code. Subclassing keeps your changes isolated to your specific use case.
  • Maintain Clear State Links: The parent reference ensures translate() always uses the correct encoding from the original Data instance, avoiding disconnected state or global variables.
  • Follow Single Responsibility: The translate() method on the score container does one specific job—translating scores using the parent's encoding—keeping your code clean and focused.

内容的提问来源于stack exchange,提问作者codebrotherone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:04:38