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.
- reference copy
- 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
Applying Udfs on Groupeddata in Pyspark (With Functioning Python Example)
Possible to Share In-Memory Data Between 2 Separate Processes
Aes Python Encryption and Ruby Encryption - Different Behaviour
Why Can't Python Find Shared Objects That Are in Directories in Sys.Path
Rally APIs: How to Copy Test Folder and Member Test Cases
Difference Between Multiple If's and Elif'S
Which of These Scripting Languages Is More Appropriate for Pen-Testing
Vscode -- How to Set Working Directory for Debugging a Python Program
Learning Ruby from Python; Differences and Similarities
Programmatically Extract Data from an Excel Spreadsheet
How to Validate a Date String Format in Python
Swift Playground Error: Module 'Python' Has No Member Named 'Import'