python object typecasting - python

Ive been trying search how to pass object reference in python and type cast it similar to Java but no to avail. I duno if this topic exists somewhere here.
My trouble is i have to pass the object reference to a class constructor. But i duno how to typecast the reference to an object. In java though I have accomplish this but i have to transfer the code to the server side.
many thanks,
Jack
class SearchRectangle:
def __init__(self, lower_left_subgrid_x, lower_left_subgrid_y, rectangle_width, rectangle_height):
self.min_subgrid_x = int(lower_left_subgrid_x)
self.max_subgrid_x = int(self.min_subgrid_x + rectangle_width -1)
self.min_subgrid_y = int(lower_left_subgrid_y)
self.max_subgrid_y = int(self.min_subgrid_y + rectangle_height -1)
...blah
class SearchRectangleMultiGrid:
# parent rectangle should be a SearchRectangle instance
def __init__(self, parent_rectangle):
self.parent_rectangle = SearchRectangle()parent_rectangle
# test codes
test_rect = SearchRectangle(test_subgrid.subgrid_x, test_subgrid.subgrid_y, 18, 18)
print "\n\nTest SearchRectangle";
print test_rect.to_string()
print test_rect.sql_clause
test_rec_multi = SearchRectangleMultiGrid(test_rect)
print "\n\nTest SearchRectangleMulti"
test_rec_multi.parent_rectangle.to_string()

Python is a dynamically typed language and as such, it doesn't make much sense to cast something unless you specifically need it in that type.
In Python you should use Duck Typing instead: http://en.wikipedia.org/wiki/Duck_typing
So instead of trying to convert parent_rectangle to a SearchRectangle() you should simply test if SearchRectangle() has the properties you need.
Or if you really want to be sure that you'll always get a SearchRectangle(), use isinstance like this:
if isinstance(parent_rectangle, SearchRectangle):
This might be a good read for you: http://dirtsimple.org/2004/12/python-is-not-java.html

There's no reason to cast anything in python. What are you trying to do? Just use the object like you would, and if it's not of the correct type it will fail. There's no such thing as casting since variable names don't have a type associated with them.

Further explanation:
Casting is the act of taking a pointer/reference to one type of object, and say to the compiler "Yeah, I know this is a foo reference but please pretend it is a bar reference".
Python do not have pointers/references in that sense (although in another sense, everything is references). Also, the compiler/interpreter doesn't care what the type is in the first place. Hence, casting is both impossible and pointless.
So in your example: Just skip the type casting. It'll work anyway. And if it doesn't. then make a question on that problem.

Related

Duck Typing in Python (in order to mimic a String)

Duck Typing in general is explained here: https://stackoverflow.com/a/4205163/19446851.
What does Duck Typing mean in Python? Is it really possible to make one type look like another type. Can I have an own class that "looks and quacks" like a string?
See the following example:
from dataclasses import dataclass
#dataclass
class ColoredObject:
color : ...
name : ...
def __str__(self):
return self.color + " " + self.name
x = ColoredObject("red", "circle")
print("I have a " + x + ".")
That code does not work because strings and objects of the type ColoredObject cannot be concatenated. If in Python it would actually be possible to make ColoredObject "look and quack" like a string, there should be a way to concatenate both without the explicit conversion.
The following is a more practical example. I try to make the class MutableText "looking and quacking" like a string so that I can use it in an XML Element Tree.
import xml.etree.cElementTree as ET
root = ET.Element("root_node")
class MutableText:
def __init__(self, init_text):
self.text = init_text
mutable_contents = MutableText("ZigZag")
ET.SubElement(root, "child_node").text = mutable_contents
tree = ET.ElementTree(root)
tree.write("filename.xml")
The goal is that line ET.SubElement(root, "child_node").text = mutable_contents works. What can I do to achieve this?
The error message, that I get with the code is TypeError: cannot serialize <__main__.MutableText object at 0x7fafc0099e20> (type MutableText)
I already got the advice to inherit from str class. But this is not Duck Typing. This is static typing like in C++ or Java.
Another advice to use ET.SubElement(root, "child_node").text = mutable_contents.text is good. But that is also not Duck Typing. And that means, I always have to update the ElementTree whenever mutable_contents changes. (This is actually my motivation, why I ask this academic question. I am trying to find a solution for not having to always do this update.)
I also got the comment that ElementTree actually expects a string and not a MutableString. But why do people then say, Python uses Duck Typing? And why don't I get the error Message that a string is expected where a MutableString is provided?
Obviously there is something missing in my code in order to make MutableText like a string? But what is missing? And shouldn't Python give me an error message when it tries to call something from MutableText, which is missing?
Is it really possible to make one type look like another type?
This is quite typical of people who come from a statically typed language to interpret duck typing but it misses a significant aspect of the whole deal: it isn't that you are faking another type it is that your code relies on behaviour instead of types.
say we have this function:
def example_math_equation(a,b):
return a + 4*b
This doesn't dictate anything about what types a or b have to be, just that it should be valid to multiply b by an integer and that a can be added to the result. as such this code would be applicable to not just numbers but also sequences:
>>> example_math_equation("foo", "bar")
'foobarbarbarbar'
This is the idea of duck typing, that you avoid checking for types of data as much as possible and just assume they support the operations you need and if they don't you get an error. Then if someone wants to make a new data type - not with the intent to mimic another well defined data type but just to behave differently - then it could be used instead.
If you don't want to do duck typing, you just want to cheat and mimic the str class there is a route that exists:
class MockStr:
def __init__(self, initial_text):
self._TEXT = initial_text
def make_wrapper_method(methodname):
"makes a method that will forward to ._TEXT field"
def wrapper_method(self, *args, **kw):
#print("CALLED WRAPPER", methodname)
return getattr(self._TEXT, methodname)(*args, **kw)
return wrapper_method
for methodname, underlying_method in vars(str).items():
if not callable(underlying_method) or methodname in dir(MockStr):
continue
setattr(MockStr, methodname, make_wrapper_method(methodname))
x = MockStr("hi there")
print(x + " got added to a string")
But don't go down this route, the first issue you will come across is that because str can't be added to any other built in type it doesn't bother defining a __radd__ so "a" + x will fail unless you do that yourself, but more specifically if your goal is to make a mutable string you truely shouldn't do this because your object won't be immutable
If a class defines mutable objects and implements an __eq__() method,
it should not implement __hash__(), since the implementation of
hashable collections requires that a key’s hash value is immutable
and if the library you are using expects the strings to be immutable and makes certain optimisations based on that then the whole journey of trying to accomplish that will just be a wild goose chase, you are much better off to learn what behaviours (methods) the library is expecting and see if you can reasonably provide those with a data type that also has the behaviour you want.

Calling a function in Pycharm

I am new in Python and I am currently learning OOP in Pycharm.
When I type in a simple function like type(mylist), I dont see the answer in the console, I have to add print in the beginning, same with any other function, although in the tutorials I am currently following, they just call the function by typing its name and adding a parameter.
Same with my first attribute (please see screenshots)
Please help me if you know how to get around it.
You need to separate the object instantiation from the print()
my_dog = Dog(mybreed='lab')
print(my_dog)
Instead of:
print(my_dog=Dog(mybreed='lab'))
You could either split it to two lines:
my_dog = Dog(mybreed='lab')
print(my_dog)
Or, if you don't need the my_dog variable:
print(Dog(mybreed='lab'))
In python variable_name = expression can't be regarded as expression to be used as parameter, so print(my_dog=Dog(mybreed='lab')) will raise an error.
You can sure finish your job by this way:
my_dog = Dog(mybreed='lab') # assign the variable my_dog
print(my_dog) # print the variable my_dog
If you don't need variable my_dog, you can just use print(Dog(mybreed='lab')), which will surely work.
If you do prefer assign a variable and pass it as a parameter (just like C++ does), you can use Assignment Expressions(also The Walrus Operator) := in Python 3.8 or higher version:
print(my_dog:=Dog(mybreed='lab'))
But just keep it in mind that this operator maybe not as convenient as you think!

Is using "type" as an attribute name a bad practice?

I have the following django model:
class SomeProfile(models.Model):
type = models.CharField(max_length=1)
Is using "type" as an attribute name considered a bad practice?
Here the attribute is not shadowing "type", so it's not the same question as this one
There's nothing wrong with it. It's not a member of python's reserved keywords.
However, naming a method type() would probably be confusing...
General rule is: don't use names that are taken (e.g. type, file, int, etc.) regardless of whether they're in a "reserved" keywords list or not (since python allows it, it's not really "reserved"). This is mainly important to avoid getting into trouble when you actually need to use the real object (without noticing that you overrode it locally).
If you really want to use one of those names, just append _ at the end (e.g. type_).
In your case, since you're specifying type as a class attribute, it should be considered safe since it can only be accessed through its class (self.type or SomeProfile.type).
Yes - its bad practice. type is very general word from keyword perspective though not a reserved keyword. Even though its not giving any problems currently in your application but it might give in future as it could have been used in some already existing libraries or python extensions.
Example: type being used as a function to get TypeCast information of variable
name = "John"
age = 12
print type(name)
## Above line will return "<type 'str'>"
print type(age)
## Above line will return "<type 'int'>"
Usage of type being used as an attribute is a bad practice.

Python 2 : How do I check type equality with created classes ? (not between objects)

I've got a defined class (what's inside is useless to the problem):
class AllyInstance(dict):
def __init__(self,name,pyset,number,gender='none'):
for dicopoke_loop_enemy in dicopoke[name]:
self[dicopoke_loop_enemy]=dicopoke[name][dicopoke_loop_enemy]
self['set']=pyset
self['status']='Normal'
self['hp']=pyset['stats']['hp']
self['boosts']={'atk':0,'def':0,'spa':0,'spd':0,'spe':0}
self['secondarystatuses']=[] #leech seed, confusion ...
self['gender']=gender
self['name']=name
self['number']=number
I create an instance of the class :
someinstance=AllyInstance( - include here the stuff to enter which is rather long - )
And later on, I want to test if someinstance's type is AllyInstance - my class. But
type(someinstance)==AllyInstance
yields False.
That is probably, because asking type(someinstance) yields:
__main__.AllyInstance
So, I try
type(someinstance)==__main__.AllyInstance
and it yields False. (if asking for __ main __ makes no sense, I don't know, i'm a beginner)
According to How to check class equality in Python 2.5? I could simply create an useless instance of AllyInstance and use this to check the equality.
But I'd still like to know how to proceed without creating useless instances, because I'd really like to avoid this.
Something, like type(an object)==(a class name).
How should I proceed ?
if isinstance(foo, AllyInstance):
For more info : python doc
You should instead use if isinstance(someinstance, AllyInstance).
Incidentally, it is not a great idea to put the word "instance" in a class name.

Is it safe to use the python word "type" in my code?

Can I use the word type in my own code or is it reserved? My function header:
def get(
self,
region='Delhi',
city='Delhi',
category='Apartments',
type='For sale',
limit=60,
PAGESIZE=5,
year=2012,
month=1,
day=1,
next_page=None,
threetapspage=0,
):
Using type as a keyword argument to a function will mask the built-in function "type" within the scope of the function. So while doing so does not raise a SyntaxError, it is not considered good practice, and I would avoid doing so.
Neither. It's not a reserved word (a list of which can be found at http://docs.python.org/reference/lexical_analysis.html#keywords ), but it's generally a bad idea to shadow any builtin.
While others have pointed out that it's bad form to shadow python built-ins, this is only the case when either name a function or function parameter as type, however -
It should be noted that the python built-in type is not shadowed in any way if you were to name a class attribute as type.
Even when referencing your class attribute, it would always be prefixed by the class instance self or a custom instance variable - and the python built-in would not be hindered.
For example:
Okay:
>>> class SomeClass():
... type = 'foobar'
...
... def someFunction(self):
... return self.type
Not Okay:
>>> def type(): # Overrides python built-in in global scope
... pass
...
>>> def foobar(type):
... return type # Overrides python built-in within func
That is more than a decade old question and to be on the safe side, I would recommend using kind instead of type as argument.
For a long time I was considering building a rename recommendation for all reserved or builins, but seeing your question made me finally do it.
Please check python-keyword-aliases.md and feel free to propose new entries to that list.
type should absolutely be consider a reserved word. While it can be tempting to use this word for database fields, consider that the fact that type() is one of the most important debugging/ testing functions because it tells you the class of an object.
$ python
>>> x = 5
>>> s = "rockets"
>>> y = [1,2,3]
>>> print(type(x))
class 'int'
>>> print(type(s))
class 'str'
>>> print(type(y))
class 'list'
An atlas would be classified a type of book, but consider using the word "category" instead.
A definitive con with shadowing builtin variables like type and id: if you happen to copy/paste your code that overshadows id for example, and then you replace all the instances of your variable with something else, but forget to rename one instance so you still have dangling id used, the code will still be syntactically valid and linters may very well not even find the error, but you'll get really really weird results when you run the code, because id won't be a string or number as you expected. It'll be the builtin function id!
This tripped me up badly a few times.

Categories