I think you seem to understand the idea of inheritance in python (e.g. class Subclass(Superclass): )  so I won't cover that here.
The classes you want to 'attach' can be treated as any other variable within the Weapon class. 
class Enchantment(object):
    def __init__(self, name, type):
        self.name = name
        self.type = type
        # can define more member variables here, and set with setter methods
    # more Enchantment methods here...
class Weapon(object):
    def __init__(self, name, type)
        self.name = name
        self.type = type
        self.enchantments = []
        # more Weapon member variables here
    def add_enchantment(self, enchantment):
        # any logic you need to check when adding an enchantment
        self.enchantments.append(enchantment)
Then in wherever your game code is running you could do
sword = Weapon('My sword', 'sword')
fire_enchantment = Enchantment('Fireball', 'fire')
sword.add_enchantment(fire_enchantment)
You can then add methods on the Weapon class to do things with the enchantments/add certain logic.
The enchantment is still an instance of an object, so if you access it in the list (maybe by identifying it by its name, or looping through the list) all its methods and variables are accessible. You just need to build an interface to it via the Weapon class e.g. get_enchantment(self, name), or have other methods in the Weapon class interact with it (e.g. when you attack you might loop through the enchantments and see if they add any extra damage).
There's obviously design considerations about how you design your classes (the above was thrown together for example and doesn't include inheritance). For example you might only allow one enchantment per weapon, in which case you shouldn't use a list in the weapon object, but could just set self.enchantment = None in the constructor, and set self.enchantment = enchantment in the add_enchantment method.
The point I'm making is you can treat instances of Enchantment or other 'attachable' classes as variables. Just make sure you create an instance of the class e.g. fire_enchantment = Enchantment('Fireball', 'fire').
There's plenty of reading out there in terms of inheritance and OOP in general. Hope this helps!
Additional answer from OP
I think the Mixin pattern is what I was looking for. After digging around more I found this post which has an answer for dynamic mixin's.