How to Copy a Class

How to copy a class?

In general, inheritance is the right way to go, as the other posters have already pointed out.

However, if you really want to recreate the same type with a different name and without inheritance then you can do it like this:

class B(object):
x = 3

CopyOfB = type('CopyOfB', B.__bases__, dict(B.__dict__))

b = B()
cob = CopyOfB()

print b.x # Prints '3'
print cob.x # Prints '3'

b.x = 2
cob.x = 4

print b.x # Prints '2'
print cob.x # Prints '4'

You have to be careful with mutable attribute values:

class C(object):
x = []

CopyOfC = type('CopyOfC', C.__bases__, dict(C.__dict__))

c = C()
coc = CopyOfC()

c.x.append(1)
coc.x.append(2)

print c.x # Prints '[1, 2]' (!)
print coc.x # Prints '[1, 2]' (!)

How to copy a Python class instance if deepcopy() does not work?

I have mostly figured it out. The only problem which I cannot overcome is knowing an acceptable set of initialization arguments (arguments for __init__) for all classes. So I have to make the following two assumtions:

1) I have a set of default arguments for class C which I call argsC.
2) All objects in C can be initialized with empty arguments.

In which case I can
First:
Initialize a new instance of the class C from it's instance which I want to copy c:

c_copy = c.__class__(**argsC)

Second:
Go through all the attributes of c and set the attributes c_copy to be a copy of the attributes of c

for att in c.__dict__:
setattr(c_copy, att, object_copy(getattr(c,att)))

where object_copy is a recursive application of the function we are building.

Last:
Delete all attributes in c_copy but not in c:

for att in c_copy.__dict__:
if not hasattr(c, att):
delattr(c_copy, att)

Putting this all together we have:

import copy

def object_copy(instance, init_args=None):
if init_args:
new_obj = instance.__class__(**init_args)
else:
new_obj = instance.__class__()
if hasattr(instance, '__dict__'):
for k in instance.__dict__ :
try:
attr_copy = copy.deepcopy(getattr(instance, k))
except Exception as e:
attr_copy = object_copy(getattr(instance, k))
setattr(new_obj, k, attr_copy)

new_attrs = list(new_obj.__dict__.keys())
for k in new_attrs:
if not hasattr(instance, k):
delattr(new_obj, k)
return new_obj
else:
return instance

So putting it all together we have:

argsC = {'a':1, 'b':1}
c = C(4,5,r=[[1],2,3])
c.a = 11
del c.b
c_copy = object_copy(c, argsC)
c.__dict__

{'a': 11, 'r': [[1], 2, 3]}

c_copy.__dict__

{'a': 11, 'r': [[1], 2, 3]}

c.__dict__

{'a': 11, 'r': [[1, 33], 2, 3]}

c_copy.__dict__

{'a': 11, 'r': [[1], 2, 3]}

Which is the desired outcome. It uses deepcopy if it can, but for the cases where it would raise an exception, it can do without.

How to copy a class object in python

You're right, using deepcopy from the built-in copy module is the way to go, since you want the exact replica of the Object Foo.

from copy import deepcopy

class Foo:
...

Foo_copy = deepcopy(Foo)
# Foo_copy(5) will work exactly the same way Foo(5) would work without affecting it.
# Foo_copy = deepcopy(Foo(5)) works the same way as well, but here, Foo_copy.nums will be 5.

Here, passing the object Foo(5) will return a Foo object, passing it without any args will return __name__.Foo

Is this a good way to copy a class?

There are two kinds of copying objects.

  1. reference copy
  2. value copy

to copy an object by reference you can just use '=' operator.

e.g:

var o1 = new ClassClass();
var o2 = o1;

to copying an object by value, there are several ways, such as:

Copy by a constructor (as you wrote)

    public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }

public Student(Student std)
{
FirstName = std.FirstName;
LastName = std.LastName;
}
}

Make a helper class an pass the s1 as input and return s2 as
result

    static void Main(string[] args)
{
var s1 = new Student();
var s2 = ClassHelper.CopyObject(s1);

}

public static class ClassHelper
{
public static Student CopyObject(Student std)
{
var newStudent = new Student()
{
FirstName = std.FirstName,
LastName = std.LastName
};
return newStudent;
}
}

Generic Copy Objects (using Refelection)

private static void CopyClass<T>(T copyFrom, T copyTo, bool copyChildren)
{
if (copyFrom == null || copyTo == null)
throw new Exception("Must not specify null parameters");

var properties = copyFrom.GetType().GetProperties();

foreach (var p in properties.Where(prop => prop.CanRead && prop.CanWrite))
{
if (p.PropertyType.IsClass && p.PropertyType != typeof(string))
{
if (!copyChildren) continue;

var destinationClass = Activator.CreateInstance(p.PropertyType);
object copyValue = p.GetValue(copyFrom);

CopyClass(copyValue, destinationClass, copyChildren);

p.SetValue(copyTo, destinationClass);
}
else
{
object copyValue = p.GetValue(copyFrom);
p.SetValue(copyTo, copyValue);
}
}
}

Write an extension method for this class and I recommended to do this.

public static class ExtensionClass
{
public static Student CopyAsNewObject(this Student std)
{
var newStudent = new Student()
{
FirstName = std.FirstName,
LastName = std.LastName
};
return newStudent;
}
}

static void Main(string[] args)
{
var s1 = new Student();
var s2 = s1.CopyAsNewObject();
}

(C#) How to copy classes by value type and not reference type?

Perform a Deep or Shallow Copy depending on your needs.
https://learn.microsoft.com/en-us/dotnet/api/system.object.memberwiseclone?view=netframework-4.8

How to copy properties of one class to another in javascript, including methods

You can iterate the property names of B's prototype and assign them to the instance of a excluding the constructor in the following way:

class A {
myFunc() {
throw 'I have not been created yet'
}
}
class B {
myFunc() {
console.log(`it's all good now!`)
}
}

let a = new A();
let b = new B();
//Object.assign(a, b)

for (const prop of Object.getOwnPropertyNames(B.prototype).filter(prop => prop !== "constructor"))
a[prop] = B.prototype[prop]

// explicitly copying the method works
//a.myFunc = b.myFunc;

a.myFunc();


Related Topics



Leave a reply



Submit