Why does my class run automatically without calling it? - python

name_player = None
health_player = None
inventory_player = []
class engine:
print name_player
I have no idea why this runs without calling it with engine()

The Python interpreter starts by reading your file, one line at a time.
Step 1:
name_player = None adds name_player : None to locals()
Step 2 and 3 proceed in the same way.
Step 4: class engine: Python sees a class and prepares to load the definition into memory. So it's going to read the class and put all of the fields and method definitions into some runtime dictionary probably. In order to do that, it needs to execute the statements in the class.
So normally a class might look like
class Foo():
def my_method():
return "I'm foo!"
This would define a method, and put that definition with the class definition on the heap.
So your definition proceeds as follows. We've started creating the class object and then we come across a statement, so the interpreter executes it. In your case, it's a print statement, so you see it executed.
You'll see now if you call engine(), another print won't happen.
What you probably want is to have this statement in a constructor like so:
class engine:
def __init__(self); #__init__() is a constructor in Python
print name_player
For more information about classes in Python, see https://docs.python.org/2/tutorial/classes.html

When you define a class, python evaluates the statements making up the class's definition. If those statements have side effects, for example sending text to the standard output, then that text will get sent.
If you were to instantiate this, by calling engine(), you would get back an empty object.

Related

Is it a good practice to keep reference in a class variable to the current instance of it?

I have a class that will always have only 1 object at the time. I'm just starting OOP in python and I was wondering what is a better approach: to assign an instance of this class to the variable and operate on that variable or rather have this instance referenced in the class variable instead. Here is an example of what I mean:
Referenced instance:
def Transaction(object):
current_transaction = None
in_progress = False
def __init__(self):
self.__class__.current_transaction = self
self.__class__.in_progress = True
self.name = 'abc'
self.value = 50
def update(self):
do_smth()
Transaction()
if Transaction.in_progress:
Transaction.current_transaction.update()
print Transaction.current_transaction.name
print Transaction.current_transaction.value
instance in a variable
def Transaction(object):
def __init__(self):
self.name = 'abc'
self.value = 50
def update(self):
do_smth()
current_transaction = Transaction()
in_progress = True
if in_progress:
current_transaction.update()
print current_transaction.name
print current_transaction.value
It's possible to see that you've encapsulated too much in the first case just by comparing the overall readability of the code: the second is much cleaner.
A better way to implement the first option is to use class methods: decorate all your method with #classmethod and then call with Transaction.method().
There's no practical difference in code quality for these two options. However, assuming that the the class is final, that is, without derived classes, I would go for a third choice: use the module as a singleton and kill the class. This would be the most compact and most readable choice. You don't need classes to create sigletons.
I think the first version doesn't make much sense, and the second version of your code would be better in almost all situations. It can sometimes be useful to write a Singleton class (where only one instance ever exists) by overriding __new__ to always return the saved instance (after it's been created the first time). But usually you don't need that unless you're wrapping some external resource that really only ever makes sense to exist once.
If your other code needs to share a single instance, there are other ways to do so (e.g. a global variable in some module or a constructor argument for each other object that needs a reference).
Note that if your instances have a very well defined life cycle, with specific events that should happen when they're created and destroyed, and unknown code running and using the object in between, the context manager protocol may be something you should look at, as it lets you use your instances in with statements:
with Transaction() as trans:
trans.whatever() # the Transaction will be notified if anything raises
other_stuff() # an exception that is not caught within the with block
trans.foo() # (so it can do a rollback if it wants to)
foo() # the Transaction will be cleaned up (e.g. committed) when the indented with block ends
Implementing the context manager protocol requires an __enter__ and __exit__ method.

Using Python eval to evaluate classes

How I can use eval to made class definitions inside other class ?
evalstr = str("class MyScreen(Screen):\n\tpass\n")
eval(evalstr)
I want to execute this code in other class method. But it returns an error.
Use the type function instead:
MyScreen = type("MyScreen", (Screen,), {})
This is the correct way to create a class at run-time (and in fact is essentially what executing a class statement does, since type is also the default metaclass in Python).
You can also simply define the class the "normal" way; there's nothing that says a class statement must be at the global level of a module:
class Something(object):
# Define a new class here...
class MyScreen(Screen):
pass
def __init__(self):
"""Initialize a Something object"""
# ... or here
class MyScreen(Screen):
pass
You want exec not eval here (security concerns aside)
evalstr = str("class MyScreen(Screen):\n\tpass\n")
exec(evalstr)
eval will only evaluate an expression and return it's value. exec is used for executing arbitrary code strings as statements, which is what you need here.
But seriously this is a security disaster waiting to happen in most cases, consider alternatives (like writing the code not as a string).
EDIT:
Chepner's answer is probably the right way to go.
You can't use eval for that because class is a statement, and eval only evaluates expressions, not statements. You could use exec.

python: How do I dynamically create bound methods from user supplied source code?

I would like to construct a class in python that supports dynamic updating of methods from user supplied source code.
Instances of class Agent have a method go. At the time an instance is constructed, its .go() method does nothing. For example, if we do a=Agent(), and then a.go() we should get a NotImplementedError or something like that. The user then should be able to interactively define a.go() by supplying source code. A simple source code example would be
mySourceString = "print('I learned how to go!')"
which would be injected into a like this
a.update(mySourceString)
Further invokations of a.go() would then result in "I learned how to go!" being printed to the screen.
I have partially figured out how to do this with the following code:
import types
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class NotImplementedError(Error):
pass
class Agent(object):
def go(self):
raise NotImplementedError()
def update(self,codeString):
#Indent each line of user supplied code
codeString = codeString.replace('\n','\n ')
#Turn code into a function called func
exec "def func(self):\n"+' '+codeString
#Make func a bound method on this instance
self.go = types.MethodType(func, self)
QUESTIONS
Is this implementation sensible?
Will this implementation incur unexpected scope issues?
Is there an obvious way to sandbox the user supplied code to prevent it from touching external objects? I can think of ways to do this by supplying sets of allowed external objects, but this seems not pythonic.
Possibly useful SO posts
What's the difference between eval, exec, and compile in Python?
Adding a Method to an Existing Object
(I am working in python 2.6)

Is it bad practice to put stuff into new function properties?

Say I have a class and a function:
class AddressValidator(self):
def __init__(self):
pass
def validate(address):
# ...
def validate_address(addr):
validator = AddressValidator()
return validator.validate(addr)
The function is a shortcut for using the class, if you will. Now, what if this function has to be run thousands of times? If the validator class actually has to do something on instantiation, like connecting to a database, creating it over and over thousands of times is pretty wasteful. I was wondering if I could perhaps do something like this:
def validate_address(addr):
if not hasattr(validate_address, 'validator'):
validate_address.validator = AddressValidator()
validator = validate_address.validator
return validator.validate(addr)
Now the validator class is only instantiated once and saved "in the function", to put it that way. I've never seen this done though, so I'm guessing it's bad practice. If so, why?
Note: I know I can just cache the validator object in a module global. I'm just curious if this is a viable solution when I want to avoid littering my module.
Despite "everithing is an object", not everithing work as nice as instances of well controlled class.
This problem looks like typical case for "functor" or "callable object" as it called in python.
the code will be look something like
class AddressValidator(self):
def __init__(self):
pass
def __call__(self,address):
# ...
validate_address = AdressValidator()
or you could just define your function as shortcut to bound method
class AddressValidator(self):
def __init__(self):
pass
def validate(self,address):
# ...
validate_adress = AdressValidator().validate
I'd go with a default argument (evaluated once at function definition time and bound to the function):
def validate_address(addr, validator=AddressValidator())
return validator.validate(addr)
This is perfectly acceptable if instances of AddressValidator are considered immutable (i.e. they don't contain methods that modify their internal state), and it also allows you to later override the choice of validator should you find the need to (e.g. to provide a validator specialized for a particular country).

Object cannot be created globally but can locally python

I am defining two classes in the same module and want to use the second one in the first one (as a global variable):
class Class1(object):
global_c2 = Class2()
def foo(self):
local_c2 = Class2()
class Class2(object):
pass
global_c2 gets an error but local_c2 doesn't. This makes sense because when the compiler looks through this file it won't know that Class2 is going to exist. Also if I switch the class around so that Class2 is defined first it works.
However I was wondering if there is another way to get around this. Maybe I can somehow tell python that Class2 is going to exist so don't worry about it, or do I just have to put them in the right order?
The compiler doesn't do anything here. In both cases, exactly the same bytecode sequence is generated to look up the class at runtime and instanciate it.
What makes the difference is when the statements are run. All code in a Python module is executed top from bottom -- there is no such thing as a declaration, everything's a definition and every binding is dynamic. Code in a class definition is run when the class definition is encountered (and therefore before the second class is brought into existence and bound to the name Class2). Code in a function runs when the function is called, and because you don't call the function before the definition of the second class, it's available by the time you call that function.
That's basically what every solution boils down to: Delay binding until whatever you're binding to exists.
You can do the following (i.e. backfill the contents of Class1 once Class2 has been declared.
class Class1(object):
pass
class Class2(object):
pass
Class1.global_c2 = Class2()

Categories

Resources