Why do I need to qualify local variables? - python

In this class:
class MyClass () :
foo = 1
#staticmethod
def bar () :
print MyClass.foo
Why do I need to qualify foo with MyClass? (otherwise I get NameError: global name 'foo' is not defined.
Isn't foo local to the class MyClass?

This is because Python's scope lookup order is LEGB (locals, enclosed function, global, builtin). More details in this answer. Python has an explicit class variable, which is the first argument of the method, typically named self. Normally one would access foo by using self.foo But in this case, the function is a static method, so it does not receive an explicit class variable, so there is no alternative way to access foo. Either remove the reference to foo or remove the #staticmethod decorator from the bar()and add self as the first argument of bar().

You need to do that because the bar function is a static method. This means you can call it without regarding an instance of the containing class. IE you don't have to create an instance of the class to access that function.
You can read more about it - in the documentation

This is called class attribute
which could be accessed directly by MyClass.foo, and owned by the class.
It's not owned by the instances of the class
for self this is instance variable, each instance of a class has a new copy of the variables

Isn't foo local to the class MyClass?
Actually, no. It's local to the class statement's body, which the bar function cannot access. Once the class object created and bound to MyClass, foo becomes an attribute of the class object (just like bar FWIW), but that's namespace, not scope.
Also and FWIW, Python's staticmethod dont access the class itself. If you want a method that needs to access the class, use a classmethod instead.

In Python, the concept of "local variables" really fully exists only in functions. A function (method) inside a class does not have implicit access to the class's (or instance's) scope; you must explicitly specify the object containing the desired attribute, i.e., the class or the instance (by convention passed to the method as self). As to why it was designed that way... you'd have to ask Guido, but the Zen of Python says "explicit is better than implicit" so that might have something to do with it.

Related

Why to put a property variable in the constructor

From other languages I am used to code a class property and afterwards I can access this without having it in the constructor like
Class MyClass:
def __init__(self):
self._value = 0
#property
my_property(self):
print('I got the value:' & self._value)
In almost every example I worked through the property variable was in the constructor self._value like this
Class MyClass:
def __init__(self, value = 0):
self._value = value
To me this makes no sence since you want to set it in the property. Could anyone explain to me what is the use of placing the value variable in the constructor?
Python objects are not struct-based (like C++ or Java), they are dict-based (like Javascript). This means that the instances attributes are dynamic (you can add new attributes or delete existing ones at runtime), and are not defined at the class level but at the instance level, and they are defined quite simply by assigning to them. While they can technically be defined anywhere in the code (even outside the class), the convention (and good practice) is to define them (eventually to default values) in the initializer (the __init__ method - the real constructor is named __new__ but there are very few reasons to override it) to make clear which attributes an instance of a given class is supposed to have.
Note the use of the term "attribute" here - in python, we don't talk about "member variables" or "member functions" but about "attributes" and "methods". Actually, since Python classes are objects too (instance of the type class or a subclass of), they have attributes too, so we have instance attributes (which are per-instance) and class attributes (which belong to the class object itself, and are shared amongst instances). A class attribute can be looked up on an instance, as long as it's not shadowed by an instance attribute of the same name.
Also, since Python functions are objects too (hint: in Python, everything - everything you can put on the RHS of an assignment that is - is an object), there are no distinct namespaces for "data" attributes and "function" attributes, and Python's "methods" are actually functions defined on the class itself - IOW they are class attributes that happen to be instances of the function type. Since methods need to access the instance to be able to work on it, there's a special mechanism that allow to "customize" attribute access so a given object - if it implements the proper interface - can return something else than itself when it's looked up on an instance but resolved on the class. This mechanism is used by functions so they turn themselves into methods (callable objects that wraps the function and instance together so you don't have to pass the instance to the function), but also more generally as the support for computed attributes.
The property class is a generic implementation of computed attributes that wraps a getter function (and eventually a setter and a deleter) - so in Python "property" has a very specific meaning (the property class itself or an instance of it). Also, the #decorator syntax is nothing magical (and isn't specific to properties), it's just syntactic sugar so given a "decorator" function:
def decorator(func):
return something
this:
#decorator
def foo():
# code here
is just a shortcut for:
def foo():
# code here
foo = decorator(foo)
Here I defined decorator as a function, but just any callable object (a "callable" object is an instance of a class that defines the __call__ magic method) can be used instead - and Python classes are callables (that's even actually by calling a class that you instanciate it).
So back to your code:
# in py2, you want to inherit from `object` for
# descriptors and other fancy things to work.
# this is useless in py3 but doesn't break anything either...
class MyClass(object):
# the `__init__` function will become an attribute
# of the `MyClass` class object
def __init__(self, value=0):
# defines the instance attribute named `_value`
# the leading underscore denotes an "implementation attribute"
# - something that is not part of the class public interface
# and should not be accessed externally (IOW a protected attribute)
self._value = value
# this first defines the `my_property` function, then
# pass it to `property()`, and rebinds the `my_property` name
# to the newly created `property` instance. The `my_property` function
# will then become the property's getter (it's `fget` instance attribute)
# and will be called when the `my_property` name is resolved on a `MyClass` instance
#property
my_property(self):
print('I got the value: {}'.format(self._value))
# let's at least return something
return self._value
You may then want to inspect both the class and an instance of it:
>>> print(MyClass.__dict__)
{'__module__': 'oop', '__init__': <function MyClass.__init__ at 0x7f477fc4a158>, 'my_property': <property object at 0x7f477fc639a8>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None}
>>> print(MyClass.my_property)
<property object at 0x7f477fc639a8>
>>> print(MyClass.my_property.fget)
<function MyClass.my_property at 0x7f477fc4a1e0>
>>> m = MyClass(42)
>>> print(m.__dict__)
{'_value': 42}
>>> print(m.my_property)
I got the value: 42
42
>>>
As a conclusion: if you hope to do anything usefull with a language, you have to learn this language - you cannot just expect it to work as other languages you know. While some features are based on common concepts (ie functions, classes etc), they can actually be implemented in a totally different way (Python's object model has almost nothing in common with Java's one), so just trying to write Java (or C or C++ etc) in Python will not work (just like trying to write Python in Java FWIW).
NB: just for the sake of completeness: Python objects can actually be made "struct-based" by using __slots__ - but the aim here is not to prevent dynamically adding attributes (that's only a side effect) but to make instances of those classes "lighter" in size (which is useful when you know you're going to have thousands or more instances of them at a given time).
Because #property is not a decorator for a variable, it is a decorator for function that allows it to behave like a property. You still need to create a class variable to use a function decorated by #property:
The #property decorator turns the voltage() method into a “getter” for a read-only attribute with the same name, and it sets the docstring for voltage to “Get the current voltage.”
A property object has getter, setter, and deleter methods usable as decorators that create a copy of the property with the corresponding accessor function set to the decorated function. This is best explained with an example:
I'm guessing you're coming from a language like C++ or Java where it is common to make attributes private and then write explicit getters and setters for them? In Python there is no such thing as private other than by convention and there is no need to write getters and setters for a variable that you only need to write and read as is. #property and the corresponding setter decorators can be used if you want to add additional behaviour (e.g. logging acccess) or you want to have pseudo-properties that you can access just like real ones, e.g. you might have a Circle class that is defined by it's radius but you could define a #property for the diameter so you can still write circle.diameter.
More specifically to your question: You want to have the property as an argument of the initializer if you want to set the property at the time when you create the object. You wouldn't want to create an empty object and then immediately fill it with properties as that would create a lot of noise and make the code less readable.
Just an aside: __init__ isn't actually a constructor. The constructor for Python objects is __new__ and you almost never overwrite it.

In Python, do assignment operators access class or instance variables when passed as a default value in a class method definition?

for Python 3.7
I have a class with a class attribute (class-wide variable):
class foo:
var="value goes here"
as well as an instance variable created in the class's init method:
def __init__(self, var=var):
self.var=var
Passing class variable to parameter
The class variable has the same name as init's parameter, and this doesn't confuse the interpreter, because the interpreter treats any field to the left of an "=" sign as a new variable within the scope of the method. It accomplishes this by populating a new namespace (a dictionary of variables) for the method's scope, implemented either as an array: e.g. parameters[1] = "var" or an associative array: parameters['var'] = pointer_to_value. Then the interpreter looks inside the method body and substitutes the generic reference for any references to "var" that occur on the right side of an "=" sign. Actually, this is a lie, but it's simpler to understand that than what it really does:
The interpreter identifies the matching regular expression .*= *var(,{0,1}| *) *(;{0,1}|\n*) and then passes the corresponding pointer_to_value to the program's call stack). Because of that, the interpreter doesn't care what the parameters are named and is oblivious to the ambiguity of var=var. The fact that the ambiguity can be resolved is a side-effect of the structure of the language, rather than an intentional design decision. After all, ask yourself, when defining a method, why would you access a variable from inside of the method that you are defining? And why would you ever call an assignment operation to a variable in the parent scope from within a method definition? These are both illogical actions, and their namespace possibilities are mutually exclusive, so the interpreter never needs to address the ambiguity.
Conversely, the interpreter treats the right side of the "=" sign as an existing value and searches the class's namespace for variable definitions.
Storing parameter in Instance Variable
Within the method, the instance variable also has the same name as the class variable and the parameter, and this works inside the init method, because the instance variable is accessed via the self reference, e.g.
self.varname = varname
The problem
Method Definition
I need to access the instance variable from within the method definition of another method and I want to use the same name for this function's parameter:
def lookup(self, var=var):
print(var)
Will the expression var = var get the class attribute or the instance attribute? What does methodname(self) do with self, exactly? Is self a reference to an actual object, or does it only change the behavior of the interpreter from from static method to instance method? Does the interpreter automatically contextualize the right hand side of the "=" sign as an instance attribute of whatever object is typed into methodname(object)?
Method Body
Within the method body, if I make an assignment to var...
def lookup(self, var=var):
var = var
Will it store it in the class variable, the instance variable, or a new variable with the same name?
Will it get the class variable, instance variable, or the method's variable?
How do I explicitly reference these variables?
I have read the documentation and several OOP tutorials, and a recent book, and this is still not clear to me.
The only way you can access an instance variable is as an attribute of self.
When you just refer to var, that's never an instance variable; it's always a local, enclosing, global, or builtin variable.
In your method definition:
def lookup(self, var=var):
print(var)
… you have a parameter named var. Parameters are local variables. The print(var) inside the body prints that local variable.
What about this?
def lookup(self, var=var):
var = var
Again, var is a local variable—a parameter. So, you're just assigning the current value of that local variable to the same variable. Which has no useful effect, but of course it's perfectly legal.
Where does the parameter's value come from? At function call time, if you pass an argument, that argument gets bound to the parameter; if you don't, it gets filled in with the default value.
OK, so where does the default value come from?
At function definition time (when the def statement is executed), var is looked up in the current scope—that is, the body of the class definition—and its value is stored as a default in the function object (it should be visible as foo.lookup.__defaults__[0]).
So, the default value is "value goes here".
Notice that it's not a closure capture or other reference to the class attribute. When the class statement is executed, it uses that same class body namespace to build the class's attributes, so you end up with foo.var as another name for the same value that's in foo.lookup.__defaults__[0]. But they're completely independent names for that value; you can reassign foo.var = 3, and the default value for lookup's parameter will still be "value goes here".
So, to answer your specific questions:
Will it store it in the class variable, the instance variable, or a new variable with the same name?
None of the above. It stores it in a local variable that already exists, because it's a parameter.
Will it get the class variable, instance variable, or the method's variable?
If by "the method's variable" you mean the parameter, it's the last one.
How do I explicitly reference these variables?
The same way you explicitly reference anything else:
var is a local-enclosing-global-or-builtin variable.
self.var is an instance attribute, or a class attribute if there is no instance attribute.
type(self).var is a class attribute, even if there is an instance attribute.
The implicit method argument self is the instance. Thus, while self.var is the instance variable, you need to prefix with the class object to access the class variable. Sometimes, you may not know the class object and then you can simply use the __class__ attribute, i.e. the class variable is self.__class__.var.
To answer your three questions
1. Your assignment in the lookup method will create a new variable with the same name var.
2. It will get the argument that you passed to the method (I guess that's what you mean by "method's variable"
3. The code below shows how you can explicitly access these variables (is illustrates it in the __init__, but it doesn't really matter which method you are in.
class A(object):
var = 'class_variable'
def __init__(self, var=var):
print('Argument var={}'.format(var))
var = var
self.var = var
print('Instance var={}'.format(self.var))
print('Class var={}'.format(self.__class__.var))
print('Alternative access to Class var={}'.format(A.var))
This gives
>>> a = A()
Argument var=class_variable
Instance var=class_variable
Class var=class_variable
Alternative access to Class var=class_variable
>>> b = A('v')
Argument var=v
Instance var=v
Class var=class_variable
Alternative access to Class var=class_variable
>>> c = A()
Argument var=class_variable
Instance var=class_variable
Class var=class_variable
Alternative access to Class var=class_variable
I'm going to do my best to answer your questions but if I may isolate your problem first:
I want to use the same name for this function's parameter
Don't do this. There's no logical reason to do it and if it's confusing you now imagine how you'll feel when you look at your code in a few hours/days/weeks/months/years. Imagine how someone else looking at your code will feel.
For everything I write, imagine we have an instance named bob
This will cause bob.var to be "value goes here" every time it is instantiated. Every new object will have var set to "value goes here"
class foo:
var="value goes here"
This will cause bob.var to be whatever value gets passed to foo during instantiation. If nothing is passed, it will default to "value goes here"
def __init__(self, var=var):
self.var=var
This will print whatever is passed OR "value goes here" if nothing is passed
def lookup(self, var=var):
print(var)
This does nothing as the var in question is locally scoped and only exists until the end of the method
def lookup(self, var=var):
var = var
I hope this helps and just to reiterate: Use different variable names for your different variables.

Python memory allocation, when using bound, static or class functions?

I am curious about this: what actually happens to the python objects once that you create a class that contains each one of these functions?
Looking at some example, I see that either the bound, static or class function is in fact creating a class object, which is the one that contains all 3 function.
Is this always true, no matter which function I call? and the parent object class (object in this case, but can be anything I think) is always called, since the constructor in my class is invoking it implicitly?
class myclass(object):
a=1
b=True
def myfunct(self, b)
return (self.a + b)
#staticmethod
def staticfunct(b):
print b
#classmethod
classfunct(cls, b):
cls.a=b
Since it was not clear: what is the lifecycle for this object class, when I use it as following?
from mymodule import myclass
class1 = myclass()
class1.staticfunct(4)
class1.classfunct(3)
class1.myfunct
In the case of static, myclass object get allocated, and then the function is run, but class and bound method are not generated?
In the case of class funciton, it is the same as above?
in the case of the bound function, everything in the class is allocated?
The class statement creates the class. That is an object which has all three functions, but the first (myfunct) is unbound and cannot be called without an instance object of this class.
The instances of this class (in case you create them) will have bound versions of this function and references to the static and the class functions.
So, both the class and the instances have all three functions.
None of these functions create a class object, though. That is done by the class statement. (To be precise: When the interpreter completes the class creation, i. e. the class does not yet exist when the functions inside it are created; mind boggling, but seldom necessary to know.)
If you do not override the __init__() function, it will be inherited and called for each created instance, yes.
Since it was not clear: what is the lifecycle for this object class,
when I use it as following?
from mymodule import myclass
This will create the class, and code for all functions. They will be classmethod, staticmethod, and method (which you can see by using type() on them)
class1 = myclass()
This will create an instance of the class, which has a dictionary and a lot of other stuff. It doesn't do anything to your methods though.
class1.staticfunct(4)
This calls your staticfunct.
class1.classfunct(3)
This calls you classfunct
class1.myfunct
This will create a new object that is a bound myfunct method of class1. It is often useful to bind this to a variable if you are going to be calling it over and over. But this bound method has normal lifetime.
Here is an example you might find illustrative:
>>> class foo(object):
... def bar(self):
... pass
...
>>> x = foo()
>>> x.bar is x.bar
False
Every time you access x.bar, it creates a new bound method object.
And another example showing class methods:
>>> class foo(object):
... #classmethod
... def bar():
... pass
...
>>> foo.bar
<bound method type.bar of <class '__main__.foo'>>
Your class myclass actually has four methods that are important: the three you explicitly coded and the constructor, __init__ which is inherited from object. Only the constructor creates a new instance. So in your code one instance is created, which you have named class1 (a poor choice of name).
myfunctcreates a new integer by adding class1.a to 4. The lifecycle of class1 is not affected, nor are variables class1.a, class1.b, myclass.a or myclass.b.
staticfunct just prints something, and the attributes of myclass and class1 are irrelevant.
classfunct modifies the variable myclass.a. It has no effect on the lifecycle or state of class1.
The variable myclass.b is never used or accessed at all; the variables named b in the individual functions refer to the values passed in the function's arguments.
Additional info added based on the OP's comments:
Except for the basic data types (int, chars, floats, etc) everything in Python is an object. That includes the class itself (a class object), every method (a method object) and every instance you create. Once created each object remains alive until every reference to it disappears; then it is garbage-collected.
So in your example, when the interpreter reaches the end of the class statement body an object named "myclass" exists, and additional objects exist for each of its members (myclass.a, myclass.b, myclass.myfunct, myclass.staticfunct etc.) There is also some overhead for each object; most objects have a member named __dict__ and a few others. When you instantiate an instance of myclass, named "class1", another new object is created. But there are no new method objects created, and no instance variables since you don't have any of those. class1.a is a pseudonym for myclass.a and similarly for the methods.
If you want to get rid of an object, i.e., have it garbage-collected, you need to eliminate all references to it. In the case of global variables you can use the "del" statement for this purpose:
A = myclass()
del A
Will create a new instance and immediately delete it, releasing its resources for garbage collection. Of course you then cannot subsequently use the object, for example print(A) will now give you an exception.

When are python class properties created

class Foo:
bar = 1
......etc.
I know when creation a instance, bar is created before __init__,
I want to know if it is the very first thing to create the bar property when creating
a instance for Foo.
Also, does the bar already exists in memory before any instance is created?
Remember that in Python class is an executable statement (as too are def and import). So the answer to your question is that bar is created when the class statement executes.
Specifically, when a class statement executes, the body of the class is executed in a namespace that is usually just a dict. When the body has finished executing a class object is created with a copy of the resulting dict as the __dict__ attribute for the class.
The dict at this point contains all the names bound inside the class body bar=1 for example, but also any functions that were defined in the class body.
Instances, when they are created, don't get a copy of bar, they just refer back to the class. When you lookup a name on an instance Python looks in both the instance's __dict__ and the class's __dict__.
Those properties are stored in the the __dict__ of the class itself. They never exist on the instance (or rather the instance's __dict__) unless you assign it manually.
For example, if you use self.bar += 1 in a method you'll read the 1 from the class-level variable and assign 2 to the instance-level variable. The next time you run this statement, bar exists on the instance level so you read that 2 and replace it with 3.
State variables will be assigned before the constructor (init). So...
Class Foo:
bar = 1
def __init__(self):
bartwo = 2
would see bar take on a value of 1, before bartwo was assigned, though. My guess is your question is "If I assign a state variable before a constructor, can I use it in the constructor. Yes.

Why does "self" outside a function's parameters give a "not defined" error?

Look at this code:
class MyClass():
# Why does this give me "NameError: name 'self' is not defined":
mySelf = self
# But this does not?
def myFunction(self):
mySelf2 = self
Basically I want a way for a class to refer to itself without needing to name itself specifically, hence I want self to work for the class, not just methods/functions. How can I achieve this?
EDIT: The point of this is that I'm trying to refer to the class name from inside the class itself with something like self.class._name_ so that the class name isn't hardcoded anywhere in the class's code, and thus it's easier to re-use the code.
EDIT 2: From what I've learned from the answers below, what I'm trying to do is impossible. I'll have to find a different way. Mission abandoned.
EDIT 3: Here is specifically what I'm trying to do:
class simpleObject(object):
def __init__(self, request):
self.request = request
#view_defaults(renderer='string')
class Test(simpleObject):
# this line throws an error because of self
myClassName = self.__class__.__name__
#view_config(route_name=myClassName)
def activateTheView(self):
db = self.request.db
foo = 'bar'
return foo
Note that self is not defined at the time when you want the class to refer to itself for the assignment to work. This is because (in addition to being named arbitrarily), self refers to instances and not classes. At the time that the suspect line of code attempts to run, there is as of yet no class for it to refer to. Not that it would refer to the class if there was.
In a method, you can always use type(self). That will get the subclass of MyClass that created the current instance. If you want to hard-code to MyClass, that name will be available in the global scope of the methods. This will allow you to do everything that your example would allow if it actually worked. E.g, you can just do MyClass.some_attribute inside your methods.
You probably want to modify the class attributes after class creation. This can be done with decorators or on an ad-hoc basis. Metaclasses may be a better fit. Without knowing what you actually want to do though, it's impossible to say.
UPDATE:
Here's some code to do what you want. It uses a metaclass AutoViewConfigMeta and a new decorator to mark the methods that you want view_config applied to. I spoofed the view_config decorator. It prints out the class name when it's called though to prove that it has access to it. The metaclass __new__ just loops through the class dictionary and looks for methods that were marked by the auto_view_config decorator. It cleans off the mark and applies the view_config decorator with the appropriate class name.
Here's the code.
# This just spoofs the view_config decorator.
def view_config(route=''):
def dec(f):
def wrapper(*args, **kwargs):
print "route={0}".format(route)
return f(*args, **kwargs)
return wrapper
return dec
# Apply this decorator to methods for which you want to call view_config with
# the class name. It will tag them. The metaclass will apply view_config once it
# has the class name.
def auto_view_config(f):
f.auto_view_config = True
return f
class AutoViewConfigMeta(type):
def __new__(mcls, name, bases, dict_):
#This is called during class creation. _dict is the namespace of the class and
# name is it's name. So the idea is to pull out the methods that need
# view_config applied to them and manually apply them with the class name.
# We'll recognize them because they will have the auto_view_config attribute
# set on them by the `auto_view_config` decorator. Then use type to create
# the class and return it.
for item in dict_:
if hasattr(dict_[item], 'auto_view_config'):
method = dict_[item]
del method.auto_view_config # Clean up after ourselves.
# The next line is the manual form of applying a decorator.
dict_[item] = view_config(route=name)(method)
# Call out to type to actually create the class with the modified dict.
return type.__new__(mcls, name, bases, dict_)
class simpleObject(object):
__metaclass__ = AutoViewConfigMeta
class Test(simpleObject):
#auto_view_config
def activateTheView(self):
foo = 'bar'
print foo
if __name__=='__main__':
t = Test()
t.activateTheView()
Let me know if you have any questions.
Python has an "explict is better than implicit" design philosophy.
Many languages have an implicit pointer or variable in the scope of a method that (e.g. this in C++) that refers to the object through which the method was invoked. Python does not have this. Here, all bound methods will have an extra first argument that is the object through which the method was invoked. You can call it anything you want (self is not a keyword like this in C++). The name self is convention rather than a syntactic rule.
Your method myFunction defines the variable self as a parameter so it works. There's no such variable at the class level so it's erroring out.
So much for the explanation. I'm not aware of a straightforward way for you to do what you want and I've never seen such requirement in Python. Can you detail why you want to do such a thing? Perhaps there's an assumption that you're making which can be handled in another way using Python.
self is just a name, your self in this case is a class variable and not this for the object using which it is called,
self is treated as a normal variable and it is not defined, where as the self in the function comes from the object used for calling.
you want to treat the object reference in self as a class variable which is not possible.
self isn't a keyword, it's just a convention. The methods are attributes of the class object (not the instance), but they receive the instance as their first argument. You could rename the argument to xyzzy if you wanted and it would still work the same way.
But (as should be obvious) you can't refer to a method argument outside the body of the method. Inside a class block but outside of any method, self is undefined. And the concept wouldn't even make sense -- at the time the class block is being evaluated, no instance of the class can possibly exist yet.
Because the name self is explicitly defined as part of the arguments to myFunction. The first argument to a method is the instance that the method was called on; in the class body, there isn't an "instance we're dealing with", because the class body deals with every possible instance of the class (including ones that don't necessarily exist yet) - so, there isn't a particular object that could be called self.
If you want to refer to the class itself, rather than some instance of it, this is spelled self.__class__ (or, for new-style classes in Py2 and all classes in Py3, type(self)) anywhere self exists. If you want to be able to deal with this in situations where self doesn't exist, then you may want to look at class methods which aren't associated with any particular instance, and so take the class itself in place of self. If you really need to do this in the class body (and, you probably don't), you'll just have to call it by name.
You can't refer to the class itself within the class body because the class doesn't exist at the time that the class body is executed. (If the previous sentence is confusing, reading up about metaclasses will either clear this up or make you more confused.)
Within an instance method, you can refer to the class of the instance with self.__class__, but be careful here. This will be the instance's actual class, which through the power of inheritance might not be the class in which the method was defined.
Within a class method, the class is passed in as the first argument, much like instances are the first argument to instance methods:
class MyClass(object):
#classmethod
def foo(cls):
print cls.__name__
MyClass.foo() # Should print "MyClass"
As with instance methods, the actual class might differ due to inheritance.
class OtherClass(MyClass):
pass
OtherClass.foo() # Should print "OtherClass"
If you really need to refer to MyClass within a method of MyClass, you're pretty much going to have to refer to it as MyClass unless you use magic. This sort of magic is more trouble than it is worth.

Categories

Resources