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.
Related
I am trying to write tests for class methods but when I call them I get an AttributeError which complains the methods don't exist.
class Foo:
#staticmethod
def __method_to_test(x)
return x ** 2
Foo.__method_to_test(3)
The last line results in the following: AttributeError: type object 'Foo' has no attribute '__method_to_test'
Why can't I call the method?
Thanks to Sven Eberth, collecting their responses here.
Python Renames Methods That Start With A Double Underline
Starting a method with a double underline causes python to do something called name mangling which causes the method to be renamed from __method_to_test to _Foo__method_to_test.
Call the function like this:
Foo._Foo__method_to_test(3)
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
This is inspired by a question I just saw, "Change what is returned by calling class instance", but was quickly answered with __repr__ (and accepted, so the questioner did not actually intend to call the instance).
Now calling an instance of a class can be done like this:
instance_of_object = object()
instance_of_object()
but we'll get an error, something like TypeError: 'object' object is not callable.
This behavior is defined in the CPython source here.
So to ensure we have this question on Stackoverflow:
How do you actually call an instance of a class in Python?
You call an instance of a class as in the following:
o = object() # create our instance
o() # call the instance
But this will typically give us an error.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'object' object is not callable
How can we call the instance as intended, and perhaps get something useful out of it?
We have to implement Python special method, __call__!
class Knight(object):
def __call__(self, foo, bar, baz=None):
print(foo)
print(bar)
print(bar)
print(bar)
print(baz)
Instantiate the class:
a_knight = Knight()
Now we can call the class instance:
a_knight('ni!', 'ichi', 'pitang-zoom-boing!')
which prints:
ni!
ichi
ichi
ichi
pitang-zoom-boing!
And we have now actually, and successfully, called an instance of the class!
The short answer is that the object class has no __call__ method (you can check that with "dir(object)"). When you create an instance of a class the __init__ method is called and when you call the instance, the __call__ method is called.
Up Votes for Everyone!
Thanks for posting the question and thanks for answering.
I thought I would just share my implementation in case that helps others ...
I have a class (called RTS) and it contains an SQL Query that I access using a 'get'. The class works fine as an independent endpoint. Now I want to call that class from within the program.
Using the answer above I added the following:
class RTS(Resource):
def __call__(self):
print("In RTS")
def get(self, user_id):
try: ...
In order to call the class from elsewhere in the program I added:
getGR = RTS.get(self, user_unique_id)
Voila - I got the same info I could check on Postman returned within the program.
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])
I'm a new Python programmer who is having a little trouble using 'self' in classes. For example:
class data:
def __init__(self):
self.table = []
def add(self, file):
self.table.append(file)
data.add('yes')
In this function I want to have table be a variable stored in the class data and use add to modify it. However, when I run this script it gives me the error:
Traceback (most recent call last):
File "/Projects/Python/sfdfs.py", line 7, in <module>
data.add('yes')
TypeError: add() takes exactly 2 positional arguments (1 given)
I assume that I am trying to call the function the wrong way in this instance, as this syntax is very similar to an example in the python documentation: http://docs.python.org/3.1/tutorial/classes.html
You first need to make an instance of the class:
mydata = data()
then you can call the method -- on the instance, of course, not on the class:
mydata.add('yes')
You need to instantiate the class before you can call methods on it:
mydata = Data()
mydata.add('yes')
you are calling the add method on the class object not an instance of the class.
It looks like what you want to do is:
classInst = data() #make an instance
classInst.add("stuff") #call the method
When add is invoked on an instance object, the instance object is passed as the self argument to the method. Having the self argument differentiates class methods from instance methods.
You are trying to call data.add() somewhat like you would call a static method in Java.
Try doing this instead:
d = data()
d.add('yes')
The self parameter tells the method that it operates on an object of type data.