Create Object of a Class based on another Objects Attributes in Python - python

What would be the best practice to create a new object, which uses the attributes of an existing object of another class type in Python?
Let's say I have an object MvsObject of the class MvsClass and I want to create a new object of a different class that uses the attributes densePointClouds and sparsePointClouds and processes them with the methods of the class PointCloud.
Would the following approach be a "good practice" in Python?
class PointCloud:
def __init__(self, MvsObject):
self.densePointClouds = MvsObject.densePointClouds
self.sparsePointClouds = MvsObject.sparsePointClouds

Your solution is good. You could also use #classmethod decorator in order to define two ways to build your class (in a "classical" way, or using another instance).
class PointCloud:
def __init__(self, dense_points_cloud, sparse_points_cloud):
self.dense_points_cloud = dense_points_cloud
self.sparse_points_cloud = sparse_points_cloud
#classmethod
def from_mvs_object(cls, mvs_object):
return cls(mvs_object.dense_points_cloud, mvs_object.sparse_points_cloud)
You would instantiate it like this:
point = PointCloud.from_mvs_object(mvs_object)
Note also I renamed the attributes because using Python, it's preferred to use snake case to name your variables.

Related

Create/Initialize class from superior class' method in Python

is it possible to create/Initialize class from a superior class' method without inheritance? Currently, I have a method that returns a list of dataframes. Instead of a list I would like to have a new class being initialized that holds the tables' data but also has other methods that can be called from that new class.
A pseudocode example:
superiorObj = SuperiorClass() # initialize superior Class
tbls = superiorObj.extract_tables() #This method should initialize a new Class
clean_tbl = tbls.clean_tbl(tbl_name="Example_TBL") #Normal Dataframe Object
I am a little bit stuck how to accomplish this, without inheritance of the superior class to the new class. Any suggestions?
Max

We can create instance attrbitues for objects in Python. Can we create instance methods (not class Methods) as well in Python?

How To create a methods which are common to a particular object just like creating instance attrbitue obj.instance_attribute
A method which belongs specifically for a single object ?
The link contains the code. I need to create method only for this object and not all instance of class.
Creating class methods and attribute. The instance attrbitue. How to create instance methods
class A():
def init(self):
self.class_variable = 999999
def class_methods(self):
#available to all object
print("Hey")
obj = A()
obj.class_variable
999999
obj.class_methods()
Hey
obj.instance_attribute = 40404040 #common to particular object
obj.instance_attribute
40404040
#a method which is common to only this object
obj.new_method():
SyntaxError: invalid syntax
obj.new_mehtod(self):
SyntaxError: invalid syntax
I think you are mixing up terminology. Every "normal" method is a instance method - that means it applies the function without affecting any other instances of this class. To reference the instance, use the passed self keyword.
Defining a method for a single instance inside the generator/ class definition does not make sense in an OOP-context. If you create a car class, every instance of this class should be able to access its methods, like drive().
The only way to add a unique function is to add it after instantiating the object. This can be done with the types.MethodType method, which binds the function to the class instance:
from types import MethodType
def fly(self):
print(f"i, {self.name}, can fly")
class Car:
def __init__(self, name):
self.name = name
car_1 = Car("car one")
car_2 = Car("car two")
car_1.fly = MethodType(fly, car_1)
car_1.fly() # i, car one, can fly
car_2.fly() # AttributeError: 'Car' object has no attribute 'fly'
As you can see, car_1 has the class fly, which references car_1's name, while car_2 does not have this function.
But you should seriously reconsider what you are trying to achieve here.

Dynamic inheritance method and variable in Python

I want use a class master to control status flag to every class which I want to maintain.
But I only find one way to dynamic add function and var like below.(staticmethod and classmethod don't work)
In my case,simple variable like integer ,float,bool can't call by object sharing
I do some research from link below, there are two ways to overcome this problem => one element list or self-defined class
Passing an integer by reference in Python
I wish can find a way perfectly inheritance just like class A(Master):
or instance_a = A(),some_fun(instance_a,Master)
help me to inheritance when creat instance
Do any one know how to achieve that
class A():
pass
class Master():
g_list = []
g_var = 0
def test_method(self,val):
print('test',val)
m_attr_list = [i for i in Master.__dict__.keys() if not i.startswith('__')]
for name in m_attr_list:
setattr(A, name, getattr( Master, name))

Sharing base object with inheritance

I have class Base. I'd like to extend its functionality in a class Derived. I was planning to write:
class Derived(Base):
def __init__(self, base_arg1, base_arg2, derived_arg1, derived_arg2):
super().__init__(base_arg1, base_arg2)
# ...
def derived_method1(self):
# ...
Sometimes I already have a Base instance, and I want to create a Derived instance based on it, i.e., a Derived instance that shares the Base object (doesn't re-create it from scratch). I thought I could write a static method to do that:
b = Base(arg1, arg2) # very large object, expensive to create or copy
d = Derived.from_base(b, derived_arg1, derived_arg2) # reuses existing b object
but it seems impossible. Either I'm missing a way to make this work, or (more likely) I'm missing a very big reason why it can't be allowed to work. Can someone explain which one it is?
[Of course, if I used composition rather than inheritance, this would all be easy to do. But I was hoping to avoid the delegation of all the Base methods to Derived through __getattr__.]
Rely on what your Base class is doing with with base_arg1, base_arg2.
class Base(object):
def __init__(self, base_arg1, base_arg2):
self.base_arg1 = base_arg1
self.base_arg2 = base_arg2
...
class Derived(Base):
def __init__(self, base_arg1, base_arg2, derived_arg1, derived_arg2):
super().__init__(base_arg1, base_arg2)
...
#classmethod
def from_base(cls, b, da1, da2):
return cls(b.base_arg1, b.base_arg2, da1, da2)
The alternative approach to Alexey's answer (my +1) is to pass the base object in the base_arg1 argument and to check, whether it was misused for passing the base object (if it is the instance of the base class). The other agrument can be made technically optional (say None) and checked explicitly when decided inside the code.
The difference is that only the argument type decides what of the two possible ways of creation is to be used. This is neccessary if the creation of the object cannot be explicitly captured in the source code (e.g. some structure contains a mix of argument tuples, some of them with the initial values, some of them with the references to the existing objects. Then you would probably need pass the arguments as the keyword arguments:
d = Derived(b, derived_arg1=derived_arg1, derived_arg2=derived_arg2)
Updated: For the sharing the internal structures with the initial class, it is possible using both approaches. However, you must be aware of the fact, that if one of the objects tries to modify the shared data, the usual funny things can happen.
To be clear here, I'll make an answer with code. pepr talks about this solution, but code is always clearer than English. In this case Base should not be subclassed, but it should be a member of Derived:
class Base(object):
def __init__(self, base_arg1, base_arg2):
self.base_arg1 = base_arg1
self.base_arg2 = base_arg2
class Derived(object):
def __init__(self, base, derived_arg1, derived_arg2):
self.base = base
self.derived_arg1 = derived_arg1
self.derived_arg2 = derived_arg2
def derived_method1(self):
return self.base.base_arg1 * self.derived_arg1

Compact Class DSL in python

I want to have compact class based python DSLs in the following form:
class MyClass(Static):
z = 3
def _init_(cls, x=0):
cls._x = x
def set_x(cls, x):
cls._x = x
def print_x_plus_z(cls):
print cls._x + cls.z
#property
def x(cls):
return cls._x
class MyOtherClass(MyClass):
z = 6
def _init_(cls):
MyClass._init_(cls, x=3)
I don't want to write MyClass() and MyOtherClass() afterwards. Just want to get this working with only class definitions.
MyClass.print_x_plus_z()
c = MyOtherClass
c.z = 5
c.print_x_plus_z()
assert MyOtherClass.z == 5, "instances don't share the same values!"
I used metaclasses and managed to get _init_, print_x and subclassing working properly, but properties don't work.
Could anyone suggest better alternative?
I'm using Python 2.4+
To give a class (as opposed to its instances) a property, you need to have that property object as an attribute of the class's metaclass (so you'll probably need to make a custom metaclass to avoid inflicting that property upon other classes with the same metaclass). Similarly for special methods such as __init__ -- if they're on the class they'd affect the instances (which you don't want to make) -- to have them affect the class, you need to have them on the (custom) metaclass. What are you trying to accomplish by programming everything "one metalevel up", i.e., never-instantiated class with custom metaclass rather than normal instances of a normal class? It just seems a slight amount of extra work for no returns;-).

Categories

Resources