Yes, in Python 3.3 SimpleNamespace was added
Unlike object, with SimpleNamespace you can add and remove attributes. If a SimpleNamespace object is initialized with keyword arguments, those are directly added to the underlying namespace.
Example:
import types
x = types.SimpleNamespace()
x.happy = True
print(x.happy) # True
del x.happy
print(x.happy) # AttributeError. object has no attribute 'happy'
Answer from Vlad Bezden on Stack OverflowYes, in Python 3.3 SimpleNamespace was added
Unlike object, with SimpleNamespace you can add and remove attributes. If a SimpleNamespace object is initialized with keyword arguments, those are directly added to the underlying namespace.
Example:
import types
x = types.SimpleNamespace()
x.happy = True
print(x.happy) # True
del x.happy
print(x.happy) # AttributeError. object has no attribute 'happy'
You can use type to create a new class on the fly and then instantiate it. Like so:
>>> t = type('test', (object,), {})()
>>> t
<__main__.test at 0xb615930c>
The arguments to type are: Class name, a tuple of base classes, and the object's dictionary. Which can contain functions (the object's methods) or attributes.
You can actually shorten the first line to
>>> t = type('test', (), {})()
>>> t.__class__.__bases__
(object,)
Because by default type creates new style classes that inherit from object.
type is used in Python for metaprogramming.
But if you just want to create an instance of object. Then, just create an instance of it. Like lejlot suggests.
Creating an instance of a new class like this has an important difference that may be useful.
>>> a = object()
>>> a.whoops = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'whoops'
Where as:
>>> b = type('', (), {})()
>>> b.this_works = 'cool'
>>>
python - How to create an empty per object in selection? - Blender Stack Exchange
scripting - How to add empty object not using bpy.ops? - Blender Stack Exchange
Custom Empty Object - Python API - Developer Forum
Creating an empty object with nested attributes in Python - Stack Overflow
Videos
I've spent a long time searching on how to do this and can't seem to crack it.
I have a series of objects that inherit from a parent object. The main differences between the subclasses of the parent are different model types for an ML project.
I have a couple of datasets I'd like to pass to init and run each of the models, for example, something like:
class Dtree(Supervised_Learning):
def __init__(self, features, labels):
super().__init__(features, labels)
#other model init from sklearn here
Models = [Dtree(), KNN(), Boosting(), SVM()]
def run_model(model, features, labels)
mdl = model(features, labels)
mdl.train()
mdl.plot()
for model in Models:
run_model(model)
I've tried just passing the name with out the () and then calling the class().__init___() methods with the features and labels vars, but I can't figure out how to pass the variable for self.
Anyway to do this? Or do I need to just code a function that explicitly inits all of the model objects?
Update for 2.8 +
import bpy
for obj in bpy.context.selected_objects: # Loop over all selected objects
empty = bpy.data.objects.new(obj.name + "_Empty", None) # Create new empty object
obj.users_collection[0].objects.link(empty) # Link empty to the current object's collection
empty.empty_display_type = 'PLAIN_AXES'
empty.parent = obj
If you want the empties to be the parents :
import bpy
for obj in bpy.context.selected_objects: # Loop over all selected objects
empty = bpy.data.objects.new(obj.name + "_Empty", None) # Create new empty object
obj.users_collection[0].objects.link(empty) # Link empty to the current object's collection
empty.empty_display_type = 'PLAIN_AXES'
empty.location = obj.location
obj.parent = empty
obj.location = (0, 0, 0)
bpy.ops.object.empty_add()
You can call bpy.ops.object.empty_add() operator per object and pass the location, rotation and scale for each object as well:
Blender 2.8+
import bpy
for obj in bpy.context.selected_objects:
# Create the empty using the operator
bpy.ops.object.empty_add(type='PLAIN_AXES', location=obj.location)
# Get the newly created empty
empty = bpy.context.view_layer.objects.active
# Set the size
empty.empty_display_size = 20
# Parent the object to the empty
obj.parent = empty
Blender 2.7x
import bpy
selected_objs = bpy.context.selected_objects
for obj in selected_objs:
# Create the empty using the operator
bpy.ops.object.empty_add(type='PLAIN_AXES', location=obj.location)
# Get the newly created empty
empty = bpy.context.scene.objects.active
# Parent the object to the empty
obj.parent = empty
I think it's quite straightforward, tell me if you have problems
This is possible by placing None as the object data:
# Name, Data
o = bpy.data.objects.new( "empty", None )
bpy.context.scene.objects.link( o )
You can later access its unique empty props like any ol' empty:
o.empty_draw_size = 2
o.empty_draw_type = 'PLAIN_AXES'
For Blender 2.8, the API change a little bit:
o = bpy.data.objects.new( "empty", None )
# due to the new mechanism of "collection"
bpy.context.scene.collection.objects.link( o )
# empty_draw was replaced by empty_display
o.empty_display_size = 2
o.empty_display_type = 'PLAIN_AXES'
I made a function based on the answer by TLousky (Tested in Blender 3.2)
# Makes an empty, at location, stores it in existing collection
def make_empty(name, location, coll_name): #string, vector, string of existing coll
empty_obj = bpy.data.objects.new( "empty", None, )
empty_obj.name = name
empty_obj.empty_display_size = 1
bpy.data.collections[coll_name].objects.link(empty_obj)
empty_obj.location = location
return empty_obj
As per the type function , the third argument should be in the form of dictionary. So, for nested attributes, you can create the object before itself and then use it in the dictionary. Something like this might work -
da = type('',(),{'data':1})
a = type('',(),{'foo':da})
I dont get your point but you may use namedtuple :
>>>from collections import namedtuple
>>>foo = namedtuple('foo', "data tuple dict")
>>>foo.data = ""
''
>>> foo.tuple = ()
>>> foo.tuple
()
I'm writing a constructor to a class and I want to make a empty object if the parameters for that object are invalid, but I'm unsure what an empty object is.
In your __init__ function myList is just local variable. Use self.myList in order to make it as a class member. Of course access it in function addSomething() by using self as well: self.myList.append(x). Also you need to change signature of method addSomething from addSomething(cls, x) to addSomething(self, x)
In Python, there is difference between __init__ and __new__. That is, by the time your code hits __init__ it is already "constructed". Only then you can add new "fields" to an instance, like for example self.myList = [] in __init__.
What def addSomething(cls, x) goes, you may named it cls but it is the instance in fact. So you should write self.myList.append() instead.