I don't understand why this works;
class parentClass(object):
pass
class childClass(parentClass):
def my_meth(var):
print(var)
a = {'meth': my_meth}
x = childClass.a['meth']("Helloworld")
Whilst this fails;
class parentClass(object):
pass
class childClass(parentClass):
a = {'meth': my_meth}
def my_meth(var):
print(var)
x = childClass.a['meth']("Helloworld")
It would seem that a class is read line by line on execution and if the method definition has not been parsed before it is referenced within an attribute, an error occurs?
Is this true? Why does this occur in class/static attributes whilst you can def methods in any order and reference them from other methods written above or below them?
Is there a way to keep the class attributes at the top of the class to preserve readability and consistent layout?
It would seem that a class is read line by line on execution and if the method definition has not been parsed before it is referenced within an attribute, an error occurs?
Yes, that is true. Class definitions are executed from top to bottom, just like module-level code. You can even put things like if/else statements and for loops directly inside the class body.
Is there a way to keep the class attributes at the top of the class to preserve readability and consistent layout?
Your first example is fine. The order is not considered strange in Python.
That said, you do have potential alternatives. You could, for example, create a #classmethod to initialize class attributes at the top of the class, and then call immediately after the class declaration, e.g.
class childClass(parentClass):
#classmethod
def _initialize(cls)
cls.a = {'meth': cls.my_meth}
def my_meth(var):
print(var)
childClass._initialize()
You could even write a class decorator to do this step for you (if you think that's prettier), as they execute after the class declaration code has completed execution.
Why does this occur in class/static attributes whilst you can def methods in any order and reference them from other methods written above or below them?
Executing a function definition is different from calling the function object it creates. The former just creates the function object and assigns its name to the local context. The latter runs its code.
Classes are just fancy dicts. You can swap attributes in and out of them at runtime. When you do a self.foo() inside of a method bar, the . operator is doing an attribute lookup of the foo attribute on the self object. It's a similar idea when using cls.foo() in a classmethod.
It's entirely possible to write a function that references an attribute that doesn't exist. It will fail with an AttributeError, of course, if you call it, but if somehow the attribute gets set later, then you can call it successfully.
Related
I'm confused about this behavior,
def calc():
print ("function .. calculating")
class Calc:
print ("Class .. calculating")
Which generates this output:
Class .. calculating
Why the code inside a class gets executed even if we didn't call it or create an object, while the code inside a function doesn't get executed until we call it ?
That statement is not part of any method like __init__ or any method inside the class. As this statement is not a part of any method, the interpreter executes it before invoking the __init__ method (implicit in this case). Invoking the __init__ method means when the __init__ is called when you create an object of this class. That's why this prints it out.
Also another nice point, this would be executed multiple times when you instantiate the object. Because it is only when the interpreter is getting the class definition it executes that once. (From a discussion with Iain Shelvington)
It would be more clear from this output.
class Calc:
print ("Class .. calculating")
print(ab) #throws error
def __init__(self):
print('init')
In this case, if ab is not used earlier then it will throw you error. Very important thing is: the namespace it belongs to, check this:
class Calc:
print ("Class .. calculating")
ab=2
def __init__(self):
print('init')
print(ab) #throws error
Now it will again throw error. Since it is declared inside the class. But you can instantiate the object of the class and access it as something that is part of the class scope.
class Calc:
print ("Class .. calculating")
ab=2
def __init__(self):
print('init')
calc = Calc()
calc.ab # 2
You can check this for further reference. I want to just highlight the subtlety involved in this scope
When a class definition is left normally (via the end), a class object
is created. This is basically a wrapper around the contents of the
namespace created by the class definition; we’ll learn more about
class objects in the next section. The original local scope (the one
in effect just before the class definition was entered) is reinstated,
and the class object is bound here to the class name given in the
class definition header (ClassName in the example).
I totally agree with Tim Roberts. I'm not expert here but for specific below use case, the behavior is useful.
class Foo:
bar = 'Baz'
print(Foo.bar)
This way, you can store some data and need not to instantiate it to use the underlying data.
However, if you want to use it on class instance, it is also available.
f = Foo()
print(f.bar)
That is how the language is designed. The class body is executed when the class is defined. You can read more at docs: 9.3.1. Class Definition Syntax
I need to access a variable from a nested class. The objective is to create a Schema using the Marshmallow library. The code looks like this :
class ParserScheme(Schema):
class Meta:
# Here I meed to access the value of my_variable :
result = func(my_variable)
my_variable = 'foo'
my_parser = ParserScheme()
If I manage to pass my variable as a class attribute of the outer class (ParserScheme), then it is easy to get it into the inner class (Meta).
class ParserScheme(Schema):
class_attribute = my_variable
class Meta:
result = func(ParserScheme.class_attribute)
my_variable = 'foo'
my_parser = ParserScheme()
However I can't seem to find a way to dynamically set a class attribute. And if I set a "classic" attribute (I mean an attribute of instances of the class, not of the class itself), then I can't access it from the inner class.
I also thought of using a global variable, but that does not really quite satisfy me. Is there another way of doing this ?
I am rather new to OOP, and I am not sure I understand really well the concept of class attribute. I fear that there is an easy way to do that but I did not see it as I am to focused on the way I think this should work...
Your first example breaks because name my_variable is not yet defined when the class Meta statement's body is executed.
You second example won't work either for the same reason (my_variable is not yet defined when the class ParserScheme statement's body is executed), and if it was it would still break when executing the class Meta statement's body because it will be executed as part of the class ParserScheme statement's body hence before the name ParserScheme is defined.
What you have to understand here is that class and def are executable statements which (if at the top level of a module) are executed sequentially when the module is first imported into the current process. In the case of a class statement, the statement's body is first sequentially executed in a dedicated namespace then this namespace is passed to the metaclass constructor and used to create the class object's attributes (YourClass.__dict__).
To make a long story short: in a class statement body, you just cannot reference names that are not yet defined in the current or enclosing scope. Period.
The obvious solution here would be to define my_variable before the class statement, but I assume you want it to be more dynamic ? If yes, you'll have to define your class in a function:
def create_parser_class(my_variable):
class ParserScheme(Schema):
class Meta:
result = func(my_variable)
return ParserScheme
my_variable = 42
cls = create_parser_class(my_variable)
my_parser = cls()
But I can't garantee it will work out of the box (nor even work at all FWIW) with Marshmallow (which I never used but probably has some metaclass stuff happening). Also depending on what my_variable is used for, you may want to make sure you don't have two calls to create_parser_class with the same value as argument.
As a last note : you perhaps have a XY problem here - that's sometimes the case when someone asks how to do something a bit non-obvious or unusual. Perhaps you should edit your post to explain the "problem behind" - that is, the problem you are actually trying to solve with this "solution".
Oh and yes:
I am rather new to OOP, and I am not sure I understand really well the concept of class attribute
In Python, classes are objects too (instances of their metaclass, by default the type object), and as such they have their own attributes. Every name you define (with an assignment, a def statement, a class statement or an import statement) at the top-level of the class statement becomes an attribute of the class object (unless a custom metaclass makes some transformations on the way, that is).
Class attributes are accessible from the instances too (unless shadowed by an eponym instance variable), and are shared between all instances.
I'm trying to modify class attribute by reference to object in __init__ method and then use it in another method. Sadly the following code sample doesn't work as expected...
CODE
class Translator:
#list of attributes
parser=None
def __init__(self):
parser = Parser_class() ...
#some other commands
def Translate(self):
something=self.parser.GenerateHead() ...
#more commands
COMPILE ERR
AttributeError: 'NoneType' object has no attribute 'GenerateHead'
I know that I can give it to the Translate method as argument, I'm just curious why this statement within Python doesn't work.
You're doing your instance attributes wrong.
First off, you don't need to declare your attributes ahead of time. Putting parser = None at the top level of the class creates a class variable named parser, which I don't think is what you want. Usually in Python you can add new instance attributes at any time by a simple assignment: instance.attr = "whatever".
Second, when you want to do an instance assignment from within a method, you need to use self to refer to the instance. If you leave off self, you'll be assigning to a local variable inside your function, not to an instance or class variable. Actually, the specific name self isn't necessary, but you do need to use the first argument to the method (and it's probably not a good idea to break the convention of naming that self).
So, to fix your code, do this:
class Translator:
# don't declare variables at class level (unless you actually want class variables)
def __init__(self):
self.parser = Parser_class() # use self to assign an instance attribute
def Translate(self):
something = self.parser.GenerateHead() # this should now work
This is probably a basic question but I am new to programming. I am working with a third party python code and it provides a class with event and event delegates. The syntax for the events and event delegates are follows:
public Delegate Sub RequestEventDelegate (request As MDNPRequest, _
response as MDNPResponseParser)
public Event RequestEvent As MDNPRequest.RequestEventDelegate
I wrote the following code to subcribe to the event but is not working. I do not know what I am
doing wrong.
Mreq = MDNPRequest()
Mreq.RequestEvent += Mreq.RequestEventDelegate(handleResponseEvent)
def handleResponseEvent (request, response):
print ' event fired'
I am adding the two lines of code to the end of a function that opens up the communication channel. I also tested adding the two lines of code to a function that send a poll on the communication channel. In the second scenario the event fires and every time I execute the polling function. Does this defeat the purpose of event subscription?
I think that my problem maybe due to different functions creating instances of the same class. I would like to consolidate some of the functions into a class using the outline shown below. Method1 creates an instance 'a' of a class1 that I would like the other methods in myClass to use. I tried using a class variable which I set to a class1 instance but this is not working. I reference the class variable using the class name for example myClass.variable.somemethod from class1 but I get "Object reference not set to an instance of an object" error. What is the best approach so that all methods in myClass can have access to a? Eventually I would like to call myClass from another module.
from file1 import *
myClass:
class_variable = class1() # class1 from file1
def __init__(self)
...
def Method1(self, argument list):
# this method instantiates a
...
a = class1()
def Method2 (self):
...
a.class1method1
...
def Method3 (self):
...
a.class1method2
...
If this is actually your code:
Mreq.RequestEvent += Mreq.RequestEventDelegate(handleResponseEvent)
def handleRequestEvent (request, response):
print ' event fired'
… handleResponseEvent is not the same thing as handleRequestEvent.
As a side note, you almost never need to create an explicit delegate. It's sometimes a useful optimization, but it's one more thing you can get wrong, and one more thing that can disguise useful debugging information when you do, so it's usually simpler to write the code without it first, and only add wrap it as a delegate after it's working, if you find yourself creating a whole lot of them and want to save some memory.
From your later edits, I suspect that you're missing the fundamentals of how classes work in Python. You may want to read through the tutorial chapter, or maybe search for a friendlier/more detailed tutorial.
In particular:
I would like to consolidate some of the functions into a class using the outline shown below. Method1 creates an instance 'a' of a class1 that I would like the other methods in myClass to use. I tried using a class variable which I set to a class1 instance but this is not working.
That's not the way to do it. Class attributes, like your class_variable, are created at class creation time (that is, generally, as soon as you import the module or run the script), not instance creation time. If you want something created when instances of your class are created, you use instance attributes, not class attributes, and you set them in the __init__ method. In your case, you don't want the instance created until Method1 is called on an instance—again, that means you use an instance attribute; you just do it inside Method1 rather than __init__.
Also, class attributes are shared by all instances of the class; instance attributes, each instance has its own one. Thing about dogs: each dog has its own tail, there's not one tail shared by all dogs, so tail is an instance attribute. Often, in simple scripts, you don't notice the difference, because you only happen to ever create one instance of the class. But if you can't figure out the difference practically, think about it conceptually (like the Dog example)—and if you still can't figure it out, you almost always want an instance attribute.
I reference the class variable using the class name for example myClass.variable.somemethod from class1 but I get "Object reference not set to an instance of an object" error.
Most likely this is because class1 is a COM/interop or .NET class, and you're trying to create and use it before doing any of the relevant setup, which is only happening because you're trying to do it as soon as you import the module/run the script. If so, if you create it when you actually intended to, there won't be a problem.
What is the best approach so that all methods in myClass can have access to a?
Create an instance attribute in Method1, like this:
def Method1(self, argument list):
# this method instantiates a
...
self.a = class1()
And then use it the same way:
def Method2 (self):
...
self.a.class1method1()
...
Just doing a = whatever just creates a local variable that goes away at the end of the method. Even if it happens to have the same name as a class attribute, instance attribute, or global, you're still creating a new local variable, not modifying the thing you want to modify. Unlike some other languages, Python requires you to be explicit about what you're trying to overwrite—self.a for an instance attribute, myClass.a for a class attribute, etc.—so you don't do it by accident.
Also, note the parentheses at the end of that last expression. If you want to call a function or method, you need parentheses; otherwise, you're just referencing the method itself as a value.
Eventually I would like to call myClass from another module.
I'm not sure what you mean by "class myClass". When you call a class, that constructs a new instance of the class. You can then call that instance's methods the same way you would any other object. It doesn't matter what module it was defined in (except that you obviously have to write my_instance = mymodule.MyClass()).
Look at how you use the standard library; it's exactly the same. For example, if you import csv, you can construct a DictWriter by writing my_writer = csv.DictWriter(my_file). And then you call its methods by writing my_writer.writerow(my_row). Once you've constructed it, it doesn't matter what module it came from.
One more thing:
You've tried to define a class like this:
myClass:
You obviously can't do that; you need the class keyword. But also, in Python 2.x, you always want to give base classes, using object if you don't need anything else. Otherwise, you get an old-style class, which causes all kinds of weird quirks and limitations that you don't want to learn about and have to debug. So:
class myClass(object):
When I write class in python, most of the time, I am eager to set variables I use, as properties of the object. Is there any rule or general guidelines about which variables should be used as class/instance attribute and which should not?
for example:
class simple(object):
def __init(self):
a=2
b=3
return a*b
class simple(object):
def __init(self):
self.a=2
self.b=3
return a*b
While I completely understand the attributes should be a property of the object. This is simple to understand when the class declaration is simple but as the program goes longer and longer and there are many places where the data exchange between various modules should be done, I get confused on where I should use a/b or self.a/self.b. Is there any guidelines for this?
Where you use self.a you are creating a property, so this can be accessed from outside the class and persists beyond that function. These should be used for storing data about the object.
Where you use a it is a local variable, and only lasts while in the scope of that function, so should be used where you are only using it within the function (as in this case).
Note that __init is misleading, as it looks like __init__ - but isn't the constructor. If you intended them to be the constructor, then it makes no sense to return a value (as the new object is what is returned).
class Person(object):
def __init__(self, name):
# Introduce all instance variables on __init__
self.name = name
self.another = None
def get_name(self):
# get_name has access to the `instance` variable 'name'
return self.name
So if you want a variable to be available on more than one method, make
it an instance variable.
Notice my comment on introducing all instance vars on __init__.
Although the example below is valid python don't do it.
class Person(object):
def __init__(self):
self.a = 0
def foo(self):
self.b = 1 # Whoa, introduced new instance variable
Instead initialize all your instance variables on __init__ and set
them to None if no other value is appropriate for them.
I try to imagine what I want the API of my class to look like prior to implementing it. I think to myself, If I didn't write this class, would I want to read the documentation about what this particular variable does? If reading that documentation would simply waste my time, then it should probably be a local variable.
Occasionally, you need to preserve some information, but you wouldn't necessarily want that to be part of the API, which is when you use the convention of appending an underscore. e.g. self._some_data_that_is_not_part_of_the_api.
The self parameter refers to the object itself. So if you need to use on of the class attributes outside of the class you would it call it as the name of class instance and the attribute name. I don't think there is any guideline on when to use self, it all depends on your need. When you are building a class you should try to think about what you will use the variables you creating for. If you know for sure that you will need that specific attribute in the program you are importing your class, then add self.