calling dynamically to class method based on command line arguments - python

I need to call the class methods based on the command line argument
params = sys.argv[1].split('.')
print params
['Abc', 'test']
suite.addTest(params[0](params[1]))
Traceback (most recent call last):
File "policy.py", line 407, in <module>
suite.addTest(params[0](params[1]))
TypeError: 'str' object is not callable
Is their any way to call a class method.

In your code, params[0] is still the string 'Abc'. You need to transform it into a class that you can call.
Suppose class Abc is in module foo. Then you can do this--
import foo
MyTestClass = getattr(foo, params[0])
suite.addTest(MyTestClass(params[1])

The quick way to do it is using eval which will take the string and evaluate it in the current namespace. But eval is evil since your program input could look something like:
eval("os.remove('/')")
just as an example. Python also has a dictionary of the globals you can use this:
TestClass = globals()[params[0]]
suite.addTest(TestClass(params[1])

Related

Class Strings and print functions

I'm working on a text based game and I've done this so far:
class Map():
room1 = ('sampletext')
print(Map(room1))
but then i get an error:
Traceback (most recent call last):
File "C:/Users/Owner/Downloads/Text.py", line 3, in <module>
print(Map(room1))
NameError: name 'room1' is not defined
and I don't understand why the string from the variable isn't being printed because i am calling the class, but it says that the variable isn't recognized as a variable in the code. I want feedback so I can finish up this game.
Try this:
class Map():
room1 = ('sampletext')
print(Map.room1)
Output:
sampletext
The main problem is that you can't call a class. You can call a class method, or call a method on an instance of the class. The syntax
Map(room1)
attempts to create an instance (object) of Map, given the initialization argument room1, which should be a local variable.
With the class definition you've given, I think that the proper syntax is
print(Map.room1)
which references the value of the class attribute room1.

How can I pass dictionary to a function in python?

I am trying to pass dictionary to a function in python but it shows me error.
class stud:
def method(**arg):
print(arg)
dict1 = {1:"abc",2:"xyz"}
a = stud()
a.method(dict1)
This raises the following error:
>>> a.method(dict1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes 0 positional arguments but 2 were given
Can you tell me were I goes wrong or the right way to pass dictionary to a function?
As #Bit mentions, if method is not a static method. You need to add a self parameter.
There are two options here:
you use a normal parameter in the method:
class stud:
def method(self,arg): # normal parameter
print(arg)
you pass the dictionary as named parameters in the call:
class stud:
def method(self,**arg): # normal parameter
print(arg)
a.method(**dict1)
Personally I would go with the first one, since it is:
more efficient: you pass only a reference to the dictionary; and
if you want to alter the original dictionary, that is still possible.

Python module, class, method basicks

I am completely new to python and I have experienced, for me, strange behaviour. I have two files: foo.py and test.py
test.py:
from foo import Foo
f = Foo()
f.bar(1)
When my foo.py looks as this:
class Foo:
def bar(n):
print n
I get error message:
Traceback (most recent call last):
File "test.py", line 3, in <module>
f.bar(1)
TypeError: bar() takes exactly 1 argument (2 given)
When my foo.py looks as this:
class Foo:
def bar(x,n):
print n
I get result:
1
Why is that? Why do I need to have two params declared, even though I want to have method which takes only one? Thank you
The first argument in a method is supposed to be the object on which the method is called. That is when you call f.foo(1) it means that foo will be called with the arguments foo(f, 1). Normally one calls the first argument for self, but python doesn't care about the name, your second example the object f will be sent via the x parameter.
The reason is because Python expects the first argument to be object which is calling the function. If you're familiar with C++ or Java, it's similar to the "this" keyword. Just that Python is more particular that you explicitly declare this rather than implicitly. The standard coding convention suggests that you use "self" as the first argument, but you could use any really.
In your example,
from foo import Foo
f = Foo()
f.bar(1)
When you call the function bar, which is inside the class Foo, it can be called as Foo.bar(f,n) or f.bar(n). Here, self is 'f' or referring to the current object calling the class.
I suggest having a look at Why explicit self has to stay for clearer understanding.

Python string object not callable

I am not able to understand why I am getting a Type Error for the following statement
log.debug('vec : %s blasted : %s\n' %(str(vec), str(bitBlasted)))
type(vec) is unicode
bitBlasted is a list
I am getting the following error
TypeError: 'str' object is not callable
Shadowing the built-in
Either as Collin said, you could be shadowing the built-in str:
>>> str = some_variable_or_string #this is wrong
>>> str(123.0) #Or this will happen
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
One solution would be to change the variable name to str_ or something. A better solution would be to avoid this kind of Hungarian naming system -- this isn't Java, use Python's polymorphism to its fullest and use a more descriptive name instead.
Not defining a proper method
Another possibility is that the object may not have a proper __str__ method or even one at all.
The way Python checks for the str method is:-
the __str__ method of the class
the __str__ method of its parent class
the __repr__ method of the class
the __repr__ method of its parent class
and the final fallback: a string in form of <module>.<classname> instance at <address> where <module> is self.__class__.__module__, <classname> is self.__class__.__name__ and <address> is id(self)
Even better than __str__ would be to use the new __unicode__ method (in Python 3.x, they're __bytes__ and __str__. You could then implement __str__ as a stub method:
class foo:
...
def __str__(self):
return unicode(self).encode('utf-8')
See this question for more details.
As mouad said, you've used the name str somewhere higher in the file. That shadows the existing built-in str, and causes the error. For example:
>>> mynum = 123
>>> print str(mynum)
123
>>> str = 'abc'
>>> print str(mynum)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable

Casting in 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)

Categories