请求协助创建支持字符串、数值与null值的Metaclass(参考示例代码)
Got it, let's work through this problem together. You're looking for a metaclass that handles strings, numeric values (int/float), and null (None) values—most likely to enforce type safety for class attributes, right? Below is a practical implementation that covers both class-level static attributes and instance-level properties, with clear explanations:
Custom Metaclass for Type-Safe Attributes
First, we'll define a metaclass that enforces type constraints both when the class is defined and when instances are modified:
class TypeSafeMeta(type): # Define the allowed types: string, numbers, and None ALLOWED_TYPES = (str, int, float, type(None)) def __new__(cls, class_name, bases, class_namespace): # Add a custom __setattr__ method to the class to validate instance attributes def validated_setattr(self, attr_name, value): # Skip special attributes (like __dict__) to avoid breaking core functionality if attr_name.startswith('__'): super(self.__class__, self).__setattr__(attr_name, value) return # Check if the value is in our allowed type list if not isinstance(value, cls.ALLOWED_TYPES): raise TypeError( f"Attribute '{attr_name}' can only be str, int, float, or None. Got {type(value).__name__} instead." ) # Proceed with normal assignment if valid super(self.__class__, self).__setattr__(attr_name, value) # Attach our validation method to the class being created class_namespace['__setattr__'] = validated_setattr # Validate static class attributes during class definition for attr_name, value in class_namespace.items(): if not attr_name.startswith('__'): if not isinstance(value, cls.ALLOWED_TYPES): raise TypeError( f"Class attribute '{attr_name}' must be str, int, float, or None. Got {type(value).__name__} instead." ) # Create and return the new class return super().__new__(cls, class_name, bases, class_namespace)
How It Works
This metaclass does two key things:
- Validates static class attributes: When you define a class using this metaclass, it checks all non-special attributes (those not starting with
__) to ensure they're one of the allowed types. If not, it throws an error immediately. - Validates instance attributes: It adds a custom
__setattr__method to the class, so any time you assign a value to an instance property, it checks the type before allowing the assignment.
Example Usage
Let's test this metaclass with a sample class and some valid/invalid operations:
# Create a class using our metaclass class UserData(metaclass=TypeSafeMeta): # Valid static attributes username = "default_user" age = 25 balance = 100.50 notes = None # Initialize an instance user = UserData() # Valid assignments user.username = "jane_doe" user.age = 30 user.balance = 150.75 user.notes = "Updated profile" print(f"User: {user.username}, Age: {user.age}, Balance: {user.balance}, Notes: {user.notes}") # Output: User: jane_doe, Age: 30, Balance: 150.75, Notes: Updated profile # Invalid assignment (will throw TypeError) try: user.preferences = {"theme": "dark"} # Dict isn't allowed except TypeError as e: print(f"Error: {e}") # Output: Error: Attribute 'preferences' can only be str, int, float, or None. Got dict instead. # Invalid class definition (will throw TypeError during class creation) try: class InvalidClass(metaclass=TypeSafeMeta): invalid_attr = [1, 2, 3] # List isn't allowed except TypeError as e: print(f"Class Creation Error: {e}") # Output: Class Creation Error: Class attribute 'invalid_attr' must be str, int, float, or None. Got list instead.
Notes
- Bool values: Since
boolis a subclass ofint, boolean values (True/False) will be allowed by default. If you want to exclude booleans, modify the validation check to addor isinstance(value, bool)to the error condition. - Flexibility: You can easily adjust the
ALLOWED_TYPEStuple to include/exclude types as needed for your use case.
内容的提问来源于stack exchange,提问作者mightguy
相关产品推荐
相关产品推荐

