Casting in python - python

I have problem with casting in python.
I have a method in file module_A.py:
import Common.Models.Pax as Pax
def verify_passangers_data(self,paxes):
for i in range(len(paxes)):
pax=paxes[i]
Here is my Pax.py
class Pax:
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
#----------------------------------------------------------------------
class Adult(Pax):
def __init__(self,last_day_of_travel,first_name,last_name,nationality,address=None):
self.birth_day=datetime.today() - timedelta(days = random.randrange(6563, 20793-(date.today()-last_day_of_travel).days))
self.first_name=first_name
self.last_name=last_name
self.nationality=nationality
self.address=address
This is how I create collection in another module(module_C.py):
paxes=[]
paxes.append(Pax.Adult(last_day_of_travel,'FirstName','LastName',Nationality.Poland,DataRepository.addresses['Default']))
but, look at my output from debug probe (in wing ide)
>>> type(pax)
<class 'Common.Models.Pax.Adult'>
>>> pax is Common.Models.Pax.Adult
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
builtins.NameError: name 'Common' is not defined
How can I check is pax is instance of Adult?

How can I check is pax is instance of Adult?
Use the isinstance function:
isinstance(pax, Common.Models.Pax.Adult)
Make you have imported the class, though (e.g., import Common.Models.Pax).
(Although purists would argue that there's rarely a need to check the type of a Python object. Python is dynamically typed, so you should generally check to see if an object responds to a particular method call, rather than checking its type. But you may have a good reason for needing to check the type, too.)

You can use isinstance:
isinstance(pax, Common.Models.Pax.Adult)
Or the builtin type function:
type(pax) == Common.Models.Pax.Adult
Of course, you will have to import the module so that Common.Models.Pax.Adult is defined. That's why you're getting that error at the end.

You need to have imported the type in order to reference it:
>>> x is socket._fileobject
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'socket' is not defined
>>> import socket
>>> x is socket._fileobject
False
Presumably, you obtained the instance pointed to by pax from some other call, so you haven't actually imported the class into your namespace.
Also, is tests object identity (are these the same object?), not type. You want instanceof(pax,Common...).

You have two errors, first one is using is instead of isinstance function. Second is trying to refer module by it's absolute name, but you've imported it with alias.
Thus what you should do is:
isinstance(pax,Pax.Adult)

Related

Can't view variables within a static method

EDIT:
Ok so here is the background. I am trying to understand code written by a coworker. He has specifically written the code in the format of this example:
>>> class A:
#staticmethod
def ok(abc):
thebigone=abc
(This is a simplification but the style is the same. Namely, a variable was declared in a #staticmethod within a class)
So since I am new to his code, I wanted to see what type of data thebigone was.I called the function in the shell and tried to use the to return the contents of this variable. I ran the function ok and then tried to use the shell to print the contents of the variable thebigone but the shell returned a definition error.
Here are the commands I tried in the shell:
>>> class A:
#staticmethod
def ok(abc):
thebigone=abc
>>> A.ok('d')
>>> thebigone
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
thebigone
NameError: name 'thebigone' is not defined
>>> A.thebigone
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
A.thebigone
AttributeError: type object 'A' has no attribute 'thebigone'
After running the function, is it possible for the shell to return the contents of the variable, thebigone without altering the code? If not why is that?
Thanks
You can't create global variables spontaneously inside a method any more than you can create them spontaneously inside a function. Otherwise, you wouldn't be able to have local variables in a static method without polluting the global namespace.
In addition to Pynchia's solution, you can declare a global variable outside the class, and reference it explicitly with global:
THEBIGONE = None
class a:
#staticmethod
def ok(abc):
global THEBIGONE
THEBIGONE = abc
Or you might want to use a classmethod to make it a member of the class:
class a:
#classmethod
def ok(cls, abc):
cls.THEBIGONE = abc
Class methods are generally more useful than static methods, so consider whether that might be a better solution to your real problem.
as it is assigned, THEBIGONE is a variable (name) in the local namespace of the method, not of the class.
Try with
a.THEBIGONE = ...
Generally speaking, in Python where the assignment takes places defines the namespace where the name ends up.
So the assignment THEBIGONE = ... makes it go in the current namespace, i.e. the method's.
Unless, you explicitly specify where the name should go, e.g.
an object (usually called self in instance methods) with self.THEBIGONE = ...
a class, with a.THEBIGONE = ... in your case. Note that, as suggested in trentcl's answer, you could make the method a classmethod and avoid using the class' name explicitly.
etc.
BTW: class names should start with capital letters, using the CapWords convention, leave lowercase to variables.
Please see the guidelines described in Python's PEP-8

Make a Python class throw an error when creating a new property

Let's say this is my class:
class A:
def __init__(self):
self.good_attr = None
self.really_good_attr = None
self.another_good_attr = None
Then a caller can set the values on those variables:
a = A()
a.good_attr = 'a value'
a.really_good_attr = 'better value'
a.another_good_attr = 'a good value'
But they can also add new attributes:
a.goood_value = 'evil'
This is not desirable for my use case. My object is being used to pass a number of values into a set of methods. (So essentially, this object replaces a long list of shared parameters on a few methods to avoid duplication and clearly distinguish what's shared and what's different.) If a caller typos an attribute name, then the attribute would just be ignored, resulting in unexpected and confusing and potentially hard to figure out behavior. It would be better to fail fast, notifying the caller that they used an attribute name that will be ignored. So something similar to the following is the behavior I would like when they use an attribute name that doesn't already exist on the object:
>>> a.goood_value = 'evil'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'goood_value'
How can I achieve this?
I would also like to note that I'm fully aware that a caller can create a new class and do whatever they want, bypassing this entirely. This would be unsupported behavior, though. Making the object I do provide just creates a fail-fast bonehead check to save time against typos for those who do leverage the object I'm providing (myself included), rather than making them scratch their heads wondering why things are behaving in unexpected ways.
You can hook into attribute setting with the __setattr__ method. This method is called for all attribute setting, so take into account it'll be called for your 'correct' attributes too:
class A(object):
good_attr = None
really_good_attr = None
another_good_attr = None
def __setattr__(self, name, value):
if not hasattr(self, name):
raise AttributeError(
'{} instance has no attribute {!r}'.format(
type(self).__name__, name))
super(A, self).__setattr__(name, value)
Because good_attr, etc. are defined on the class the hasattr() call returns True for those attributes, and no exception is raised. You can set those same attributes in __init__ too, but the attributes have to be defined on the class for hasattr() to work.
The alternative would be to create a whitelist you could test against.
Demo:
>>> a = A()
>>> a.good_attr = 'foo'
>>> a.bad_attr = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 10, in __setattr__
AttributeError: A instance has no attribute 'bad_attr'
A determined developer can still add attributes to your instance by adding keys to the a.__dict__ instance dictionary, of course.
Another option is to use a side-effect of using __slots__; slots are used to save memory as a dictionary takes a little more space than just putting values directly into the C structure Python creates for each instance (no keys and dynamic table are needed then). That side-effect is that there is no place for more attributes on such a class instance:
class A(object):
__slots__ = ('good_attr', 'really_good_attr', 'another_good_attr')
def __init__(self):
self.good_attr = None
self.really_good_attr = None
self.another_good_attr = None
The error message then looks like:
>>> a = A()
>>> a.good_attr = 'foo'
>>> a.bad_attr = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'bad_attr'
but do read the caveats listed in the documentation for using __slots__.
Because there is no __dict__ instance attribute when using __slots__, this option really closes the door on setting arbitrary attributes on the instances.
A more idiomatic option is to use a named tuple.
Python 3.6 and higher
In Python 3.6 and higher, you can use typing.NamedTuple to achieve this very easily:
from typing import NamedTuple, Any
class A(NamedTuple):
good_attr: Any = None
really_good_attr: Any = None
another_good_attr: Any = None
More specific type constraints can be used if desired, but the annotations must be included for NamedTuple to pick up on the attributes.
This blocks not only the addition of new attributes, but also the setting of existing attributes:
>>> a = A()
>>> a.goood_value = 'evil'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'goood_value'
>>> a.good_attr = 'a value'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
This forces you to specify all the values at construction time instead:
a = A(
good_attr='a value',
really_good_attr='better value',
another_good_attr='a good value',
)
Doing so is typically not a problem, and when it is, it can be worked around with the judicious use of local variables.
Python 3.5 and lower (including 2.x)
These versions of Python either do not have the typing module or typing.NamedTuple does not work as used above. In these versions, you can use collections.namedtuple to achieve mostly the same effect.
Defining the class is simple:
from collections import namedtuple
A = namedtuple('A', ['good_attr', 'really_good_attr', 'another_good_attr'])
And then construction works as above:
a = A(
good_attr='a value',
really_good_attr='better value',
another_good_attr='a good value',
)
However, this does not allow for the omission of some values from calling the constructor. You can either include None values explicitly when constructing the object:
a = A(
good_attr='a value',
really_good_attr=None,
another_good_attr='a good value',
)
Or you can use one of several techniques to give the argument a default value:
A.__new__.func_defaults = (None,) * 3
a = A(
good_attr='a value',
another_good_attr='a good value',
)
make the parameter private by adding two underscores to it, ex self.__good_attr, this way someone can't set that parameter outside of the class. Then make a function that sets the __good_attr variable and have that function throw an exception if it's wrong.

Set a Read-Only Attribute in Python?

Given how dynamic Python is, I'll be shocked if this isn't somehow possible:
I would like to change the implementation of sys.stdout.write.
I got the idea from this answer to another question of mine: https://stackoverflow.com/a/24492990/901641
I tried to simply write this:
original_stdoutWrite = sys.stdout.write
def new_stdoutWrite(*a, **kw):
original_stdoutWrite("The new one was called! ")
original_stdoutWrite(*a, **kw)
sys.stdout.write = new_stdoutWrite
But it tells me AttributeError: 'file' object attribute 'write' is read-only.
This is a nice attempt to keep me from doing something potentially (probably) stupid, but I'd really like to go ahead and do it anyways. I suspect the interpreter has some kind of lookup table its using that I can modify, but I couldn't find anything like that on Google. __setattr__ didn't work, either - it returned the exact same error about the attribute being read-only.
I'm specifically looking for a Python 2.7 solution, if that's important, although there's no reason to resist throwing in answers that work for other versions since I suspect other people in the future will look here with similar questions regarding other versions.
Despite its dynamicity, Python does not allow monkey-patching built-in types such as file. It even prevents you to do so by modifying the __dict__ of such a type — the __dict__ property returns the dict wrapped in a read-only proxy, so both assignment to file.write and to file.__dict__['write'] fail. And for at least two good reasons:
the C code expects the file built-in type to correspond to the PyFile type structure, and file.write to the PyFile_Write() function used internally.
Python implements caching of attribute access on types to speed up method lookup and instance method creation. This cache would be broken if it were allowed to directly assign to type dicts.
Monkey-patching is of course allowed for classes implemented in Python which can handle dynamic modifications just fine.
However... if you really know what you are doing, you can use the low-level APIs such as ctypes to hook into the implementation and get to the type dict. For example:
# WARNING: do NOT attempt this in production code!
import ctypes
def magic_get_dict(o):
# find address of dict whose offset is stored in the type
dict_addr = id(o) + type(o).__dictoffset__
# retrieve the dict object itself
dict_ptr = ctypes.cast(dict_addr, ctypes.POINTER(ctypes.py_object))
return dict_ptr.contents.value
def magic_flush_mro_cache():
ctypes.PyDLL(None).PyType_Modified(ctypes.py_object(object))
# monkey-patch file.write
dct = magic_get_dict(file)
dct['write'] = lambda f, s, orig_write=file.write: orig_write(f, '42')
# flush the method cache for the monkey-patch to take effect
magic_flush_mro_cache()
# magic!
import sys
sys.stdout.write('hello world\n')
Despite Python mostly being a dynamic language, there are native objects types like str, file (including stdout), dict, and list that are actually implemented in low-level C and are completely static:
>>> a = []
>>> a.append = 'something else'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object attribute 'append' is read-only
>>> a.hello = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'hello'
>>> a.__dict__ # normal python classes would have this
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
If your object is native C code, your only hope is to use an actual regular class. For your case, like already mentioned, you could do something like:
class NewOut(type(sys.stdout)):
def write(self, *args, **kwargs):
super(NewOut, self).write('The new one was called! ')
super(NewOut, self).write(*args, **kwargs)
sys.stdout = NewOut()
or, to do something similar to your original code:
original_stdoutWrite = sys.stdout.write
class MyClass(object):
pass
sys.stdout = MyClass()
def new_stdoutWrite(*a, **kw):
original_stdoutWrite("The new one was called! ")
original_stdoutWrite(*a, **kw)
sys.stdout.write = new_stdoutWrite

Converting functions into a methods of a class in python

I'm trying to get the hang of python 2.6, which is my introduction to a programming language. I'm following Learn Python the Hard Way and I must have missed something. I have a set of functions that I want to combine into a class. These functions are contained here. I tried to combine these into a class called "Parsers". This code is contained here.
The functions themselves work outside of the class. I'm trying to call the functions out of the class like this:
import the module:
>>> from ex48 import parser2
Assign the class:
>>> parser_class = parser2.Parsers()
Call a function:
>>> parser_class.parse_subject(word_list, ('noun', 'player'))
I get the following:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ex48/parser2.py", line 60, in parse_subject
verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined
Not sure why it's telling me that. Can someone point me in the right direction?
You are confused as to what your code is doing.
This does not assign, a class, it creates an instance, and assigns that instance to a variable:
parser_class = parser2.Parsers()
This calls a method on that instance:
parser_class.parse_subject(word_list, ('noun', 'player'))
The following tells you that there is no global function (or indeed variable of any type) parse_verb:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ex48/parser2.py", line 60, in parse_subject
verb = parse_verb(word_list)
NameError: global name 'parse_verb' is not defined
I expect that you want to change that to verb = self.parse_verb(word_list), which will call the parse_verb method of the same object (self).
There are two problems here, one mechanical, one conceptual. I'll deal with the latter first.
The whole point of a class is that its instances represent some kind of object in your model of the world. For example, a "sentence" is an object, so it makes sense to have a class called Sentence, but a "parsers" is not an object, so Parsers is probably going to be a confused class. Looking at things less abstractly, a class usually has some kind of state, encapsulated in data members that its methods work on.
What you really have here is a parser function that returns a Sentence object (or raises a ParserError). This function could be a method of Sentence, or it could be a free function; it could also be a method of a Parser class if there were any reason for such an object to exist in your model, but there doesn't seem to be one.
If you're just looking to encapsulate all those helper functions so they don't litter the global namespace (a good idea in itself), you don't need to abuse a class to do that. Just make them local functions inside parse_sentence, or put them in a module called parsers.
Now, on to the mechanical problem: If you have a method in a class, you normally only call it through dot syntax: someObject.methodName(params). When a method calls another method of the same object, you use the special self parameter (which you've correctly listed as the first param of each method) to do that. So:
verb = self.parse_verb(word_list)
obj = self.parse_object(word_list)
… and so on for all the other method calls in your sample.
Not every language requires an explicit self like this. For example, in C++ or related languages (Java, C#, etc.), a method can call another method without specifying a target, and it's implicitly assumed that the target is this (the C++ equivalent of self).
It looks like you are working from a python interactive session.
If you've made any changes to parser2.py after importing parser2, then you have to
reload(parser2)
to make those changes known to the interactive interpreter.

Can a python module have a __repr__?

Can a python module have a __repr__? The idea would be to do something like:
import mymodule
print mymodule
EDIT: precision: I mean a user-defined repr!
Short answer: basically the answer is no.
But can't you find the functionality you are looking for using docstrings?
testmodule.py
""" my module test does x and y
"""
class myclass(object):
...
test.py
import testmodule
print testmodule.__doc__
Long answer:
You can define your own __repr__ on a module level (just provide def __repr__(...) but then you'd have to do:
import mymodule
print mymodule.__repr__()
to get the functionality you want.
Have a look at the following python shell session:
>>> import sys # we import the module
>>> sys.__repr__() # works as usual
"<module 'sys' (built-in)>"
>>> sys.__dict__['__repr__'] # but it's not in the modules __dict__ ?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '__repr__'
>>> sys.__class__.__dict__['__repr__'] # __repr__ is provided on the module type as a slot wrapper
<slot wrapper '__repr__' of 'module' objects>
>>> sys.__class__.__dict__['__repr__'](sys) # which we should feed an instance of the module type
"<module 'sys' (built-in)>"
So I believe the problem lies within these slot wrapper objects which (from what can be read at the link) have the result of bypassing the usual 'python' way of looking up item attributes.
For these class methods CPython returns C pointers to the corresponding methods on these objects (which then get wrapped in the slot wrapper objects to be callable from the python-side).
You can achieve this effect--if you're willing to turn to the Dark Side of the Force.
Add this to mymodule.py:
import sys
class MyReprModule(mymodule.__class__):
def __init__(self, other):
for attr in dir(other):
setattr(self, attr, getattr(other, attr))
def __repr__(self):
return 'ABCDEFGHIJKLMNOQ'
# THIS LINE MUST BE THE LAST LINE IN YOUR MODULE
sys.modules[__name__] = MyReprModule(sys.modules[__name__])
Lo and behold:
>>> import mymodule
>>> print mymodule
ABCDEFGHIJKLMNOQ
I dimly remember, in previous attempts at similarly evil hacks, having trouble setting special attributes like __class__. I didn't have that trouble when testing this. If you run into that problem, just catch the exception and skip that attribute.
Modules can have a __repr__ function, but it isn't invoked when getting the representation of a module.
So no, you can't do what you want.
As a matter of fact, many modules do [have a __repr__]!
>>> import sys
>>> print(sys)
<module 'sys' (built-in)> #read edit, however, this info didn't come from __repr__ !
also try dir(sys) to see __repr__ is there along with __name__ etc..
Edit:
__repr__ seems to be found in modules, in Python 3.0 and up.
As indicated by Ned Batchelder, this methods is not used by Python when it print out the a module. (A quick experiment, where the repr property was re-assigned showed that...)
No, because __repr__ is a special method (I call it a capability), and it is only ever looked up on the class. Your module is just another instance of the module type, so however you would manage to define a __repr__, it would not be called!

Categories