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

Python新手面向对象编程疑问:如何实现ObjectA.add.func1()结构

Hey there! As a fellow Python dev who’s been down the OOP learning curve, let’s figure out how to make that ObjectA.add.func1() syntax work exactly how you want.

Solution: Use a Nested Helper Class for the add Interface

First, let's break down what you need:

  • An ObjectA instance that stores functions via an add interface (with that clean add.func1() syntax)
  • An apply() method that runs all stored functions on a float vector

Here's a straightforward, beginner-friendly implementation that hits all your requirements:

class ObjectA:
    def __init__(self):
        # Internal list to hold our functions
        self._registered_functions = []
        # Initialize the `add` interface as an instance of our nested helper class
        self.add = self._FunctionAdder(self)
    
    def apply(self, vector):
        # Validate the input is a float-only vector
        if not all(isinstance(val, float) for val in vector):
            raise ValueError("Vector must contain only floating-point numbers")
        
        # Apply each function in sequence
        current_vector = vector.copy()
        for func in self._registered_functions:
            current_vector = func(current_vector)
        return current_vector
    
    # Nested helper class to handle the `add.funcX()` syntax
    class _FunctionAdder:
        def __init__(self, parent_instance):
            # Keep a reference to the parent ObjectA instance
            self.parent = parent_instance
        
        def __getattr__(self, function_name):
            # Try to fetch the function from the global scope
            import __main__
            try:
                target_func = getattr(__main__, function_name)
            except AttributeError:
                raise AttributeError(f"Function '{function_name}' doesn't exist in your scope!")
            
            # Return a wrapper that registers the function when called
            def register_function():
                if callable(target_func):
                    self.parent._registered_functions.append(target_func)
                    print(f"Registered function: {function_name}")
                else:
                    raise ValueError(f"'{function_name}' isn't a callable function!")
            return register_function

# ------------------------------
# Example Usage
# ------------------------------
def func1(vec):
    # Add 1 to every element in the vector
    return [x + 1.0 for x in vec]

def func2(vec):
    # Multiply every element by 2
    return [x * 2.0 for x in vec]

# Create our ObjectA instance
my_obj = ObjectA()

# Register functions using your desired syntax
my_obj.add.func1()
my_obj.add.func2()

# Test with a float vector
test_vec = [1.5, 2.5, 3.5]
result = my_obj.apply(test_vec)
print(result)  # Output: [5.0, 7.0, 9.0] (1.5+1)*2=5, etc.

How This Works:

  • Nested _FunctionAdder Class: This acts as the add interface. It holds a reference to the parent ObjectA instance, so it can modify the parent's list of registered functions without cluttering the main class.
  • __getattr__ Magic Method: When you call my_obj.add.func1(), Python can't find a func1 attribute on the _FunctionAdder instance, so it triggers __getattr__. This method grabs the func1 function from your global scope and returns a wrapper.
  • Wrapper Function: When you call func1() (via add.func1()), the wrapper adds the actual func1 to the parent's _registered_functions list.
  • apply() Method: Validates your input vector is float-only, then runs every registered function in the order they were added.

Bonus Tips for Beginners:

  • Private Attributes: We used _registered_functions (with a leading underscore) to signal it's an internal attribute—avoid modifying it directly from outside the class!
  • Extendability: You could add extra methods to _FunctionAdder, like list() to show all registered functions, or remove(func_name) to delete a function.
  • Alternative for Explicit Registration: If you want to avoid relying on global scope, you could modify _FunctionAdder to accept functions directly, like my_obj.add.register(func1)—but your requested add.func1() syntax is covered perfectly above.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:57:28