How to make type cast for python custom class
As noted by Anand in comments, what you're looking for is object serialization and deserialization. One way to achieve this is through the pickle (or cPickle) module:
>>> import pickle
>>> class Example():
... def __init__(self, x):
... self.x = x
...
>>> a = Example('foo')
>>> astr = pickle.dumps(a) # (i__main__\nExample\np0\n(dp1\nS'x'\np2\nS'foo'\np3\nsb.
>>> b = pickle.loads(astr)
>>> b
<__main__.Example instance at 0x101c89ea8>
>>> b.x
'foo'
Note, however, that one gotcha in using the pickle module is dealing with implementation versions. As suggested in the Python docs, if you want an unpickled instance to automatically handle implementation versioning, you may want to add a version instance attribute and add a custom __setstate__ implementation: https://docs.python.org/2/library/pickle.html#object.setstate. Otherwise, the version of the object at serialization time will be exactly what you get at deserialization time, regardless of code changes made to the object itself.
How to cast a variable to custom Class in python
You can store your class in a dictionary and then by your json
input you can convert json
to a dictionary from model
to class
:
import json
class User:
def __str__(self) -> str:
return "User Class"
class Admin:
def __str__(self) -> str:
return "Admin Class"
models= {"User": User, "Admin": Admin}
jsonStr = '{"model1":"User","model2":"Admin"}'
obj = json.loads(jsonStr)
convertedObj = {k:models[v] for k,v in obj.items()}
print(convertedObj["model1"]())
print(convertedObj["model2"]())
The output will be:
User Class
Admin Class
Casting a custom class to a dict in python
If you define __iter__
, it'll Just Work(tm):
class A(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __iter__(self):
return vars(self).iteritems()
gives
>>> A(2,3)
<__main__.A object at 0x101ea70d0>
>>> dict(A(2,3))
{'a': 2, 'b': 3}
and you can return or yield whatever you like. That said, I second the suggestion in the comments that you should really just implement a .to_dict()
method instead, as often __iter__
is too useful for other purposes to waste on this one.
How do you cast an instance to a derived class?
Rather than "casting", I think you really want to create an UnapprovedUser
rather than a User
when invoking UnapprovedUser.get()
. To do that:
Change User.get
to actually use the cls
argument that's passed-in:
@classmethod
def get(cls, uid):
ldap_data = LdapUtil.get(uid + ',' + self.base_dn)
return cls._from_ldap(ldap_data)
You'll need to do something similar in _from_ldap
. You didn't list the code for _from_ldap
, but I assume that at some point it does something like:
result = User(... blah ...)
You want to replace this with:
result = cls(... blah ...)
Remember: in Python a class object is a callable that constructs instances of that class. So you can use the cls
parameter of a classmethod to construct instances of the class used to call the classmethod.
How to cast object in Python
There is no casting as the other answers already explained. You can make subclasses or make modified new types with the extra functionality using decorators.
Here's a complete example (credit to How to make a chain of function decorators?). You do not need to modify your original classes. In my example the original class is called Working.
# decorator for logging
def logging(func):
def wrapper(*args, **kwargs):
print func.__name__, args, kwargs
res = func(*args, **kwargs)
return res
return wrapper
# this is some example class you do not want to/can not modify
class Working:
def Do(c):
print("I am working")
def pr(c,printit): # other example method
print(printit)
def bla(c): # other example method
c.pr("saybla")
# this is how to make a new class with some methods logged:
class MutantWorking(Working):
pr=logging(Working.pr)
bla=logging(Working.bla)
Do=logging(Working.Do)
h=MutantWorking()
h.bla()
h.pr("Working")
h.Do()
this will print
h.bla()
bla (<__main__.MutantWorking instance at 0xb776b78c>,) {}
pr (<__main__.MutantWorking instance at 0xb776b78c>, 'saybla') {}
saybla
pr (<__main__.MutantWorking instance at 0xb776b78c>, 'Working') {}
Working
Do (<__main__.MutantWorking instance at 0xb776b78c>,) {}
I am working
In addition, I would like to understand why you can not modify a class. Did you try? Because, as an alternative to making a subclass, if you feel dynamic you can almost always modify an old class in place:
Working.Do=logging(Working.Do)
ReturnStatement.Act=logging(ReturnStatement.Act)
Update: Apply logging to all methods of a class
As you now specifically asked for this. You can loop over all members and apply logging to them all. But you need to define a rule for what kind of members to modify. The example below excludes any method with __ in its name .
import types
def hasmethod(obj, name):
return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
def loggify(theclass):
for x in filter(lambda x:"__" not in x, dir(theclass)):
if hasmethod(theclass,x):
print(x)
setattr(theclass,x,logging(getattr(theclass,x)))
return theclass
With this all you have to do to make a new logged version of a class is:
@loggify
class loggedWorker(Working): pass
Or modify an existing class in place:
loggify(Working)
Object type casting in Python (design suggestion)
Perhaps something like this
class CommercialPack(object):
def __init__(self, pack):
self.__dict__.update(pack.__dict__)
You can even do this if you don't mind sharing state between the pack and the commercial pack
class CommercialPack(object):
def __init__(self, pack):
self.__dict__ = pack.__dict__
It should be ok in your example since you aren't keeping any other references to the pack object
eg.
PER_KM_PRICE = 100
class Pack(object):
def __init__(self, name, weight):
self.name = name
self.weight = weight
class CommercialPack(Pack):
def __init__(self, pack):
self.__dict__ = pack.__dict__
def get_delivery_price(self, distance):
return self.weight * PER_KM_PRICE * distance
def get_pack():
return Pack("pack", 20)
cp = CommercialPack(get_pack())
print cp.get_delivery_price(3)
Related Topics
How to Check If Numbers Are in a List in Python
Python Json.Loads Shows Valueerror: Extra Data
Python: Editing List While Iterating Over It
How to Normalize a Numpy Array to Within a Certain Range
How to Plot Pandas Dataframe With Date (Year/Month)
How to Map True/False to 1/0 in a Pandas Dataframe
How to Check Whether a Number Is Divisible by Another Number
How to Delete Tkinter Widgets from a Window
How to Install Pip for a Specific Python Version
Converting a List into Comma Separated and Add Quotes in Python
How to Delete the Words Between Two Delimiters
Python Pandas Dataframe Get All Combinations of Column Values
How to Convert Datetime by Removing Nanoseconds
Django: Check Whether an Object Already Exists Before Adding
How to Get All Users in a Telegram Channel Using Telethon
Passing a List of Values from Python to the in Clause of an SQL Query
How to Change Python Version in Anaconda Spyder
Python 3 Error - Typeerror: Input Expected At Most 1 Arguments, Got 3