Python: functions in a class and memory - python

If I have a class with several functions:
class Example:
def func1(self):
print 'Hi1'
def func2(self):
print 'Hi2'
def func3(self):
print 'Hi3'
If I create several instances of 'Example', does each instance store its own copies of the functions in the class? Or does Python have a smart way to store the definition only once and look it up every time an instance uses a function in the class?
Also, what about static functions? Does the class keep only one copy of each static function?

When instantiating a class, no new function objects are created, neither for instance methods nor for static methods. When accessing an instance method via obj.func1, a new wrapper object called a "bound method" is created, which will be only kept as long as needed. The wrapper object is ligh-weight and contains basically a pointer to the underlying function object and the instance (which is passed as self parameter when then function is called).
Note that using staticmethod is almost always a mistake in Python. It owes its existence to a historical mistake. You usually want a module-level function if you think you need a static method.

The functions are "stored" in the class, both static and non-static.

Related

instance methods invokation in python

does objects have its methods or invoke them from superclass in python?
for example:
class tst():
def __init__(self,name,family):
self.name=name
self.family=family
def fun(self,a,b):
print(a+b)
newtst=tst("myname","my family")
tst.fun(newtst,3,5)
newtst.fun(3,5)
in the code above does newtst object invoke fun function from tst class or it has own method and run it directly
and if the latter is true why we need to self parameter in definition class's functions
and in know that id(newtst.fun) is different from id(tst.fun) but i think that differences is because of creating new method's object in memory.
Instance methods are implemented as descriptors in python.
This implies, the separate instances are not keeping individual copies of method, but getting the same attribute of a different instances may produce individual results for each of them.
Despite we have the same function object beyond the attributes of all the instances we have, it still doesn't means that
id(tst.fun) == id(newtst.fun)
because method descriptor gives us different things when calling on a class and a class instance.
For a class we'll get an unbound method from tst, but for newtst it will be bound to an instance.

How to call static methods in functions? Scope of static methods

Suppose I create a class with a static method and want to run that method from another classes method or script function.
What is the scope of the static method?
ex:
def Class myClass:
#staticmethod
def mystaticmethod(input):
print("blah")
def scriptfunc():
myClass.mystaticmethod()
Is this valid?
What you have is valid.
But too elaborate on the purpose of #staticmethod, here's Short answer:
Declaring a #staticmethod would mean 2 things:
You don't care about the properties or attributes of a method as it's independent of other classes,
You do not require creating an __init__ or a super method to override it's content or attributes, and doesn't require a subclass/parent class to handle itself.
You can just do ClassName.methodName(), from anywhere where ClassName is accessible (so, in the same enclosing scope, or in another module after having imported ClassName.
Python has docs on namespace precedences, which you can read here. Suffice it to say; for objects in general, their 'private' namespace is entirely accessible via the dot operator, as long as the object itself is accessible. This includes all variables and functions defined directly within.

Why must instance variables be defined inside of methods?

Why must instance variables be defined inside of methods? In other words why must self only be used to define new variables inside of methods in a class. Why can't you define variables using self as part of the class, but outside of methods.
"Instance variables are those variables for which each class object has it's own copy of it" - this definition doesn't say anything about methods. So, given that the definition doesn't mention methods why can't I define an instance variable (in other words use self to define a new variable) inside of a class, but outside of a method?
Python requires the object reference (implicit or explicit this in Java, for example) to be explicit. Inside methods -- bound functions -- the first param in the function definition is the instance. (This is conventionally called self but you can use any name.)
If you define
class C:
x = 1
there is no self reference, unlike, e.g. Java, where this is implicit.
Because the mechanism which Python uses to deal with OOP are very simple. There's no special syntax to define classes really, the class keyword is a very thin layer over what amounts to creating a dict. Everything you define inside a class Foo: block basically ends up as the contents of Foo.__dict__. So there's no syntax to define attributes of the instance resulting from calling Foo(). You add instance attributes simply by attaching them to the object you get from calling Foo(), which is self in __init__ or other instance methods.
For that to answer you need to know a little bit how the Python interpreter works.
In general every class and method definition are separate objects.
What you do when calling a method is that you pass the class instance as first parameter to the method. With that the method knows on what instance it is running on (and therefore where to allocate instance variables to).
This however only counts for instance methods.
Of course you can also create classmethods with #classmethod these take the class type as argument instead of an instance and can therefore not be used to create variables on the self context.
Why must instance variables be defined inside of methods?
They don't. You can define them from anywhere, as long as you have an instance (of a mutable type):
class Foo(object):
pass
f = Foo()
f.bar = 42
print(f.bar)
In other words why must self only be used to define new variables inside of methods in a class. Why can't you define variables using self as part of the class, but outside of methods.
self (which is only a naming convention, there's absolutely nothing magical here) is used to represent the current instance. How could you use it at the class block's top-level where you don't have any instance at all (and not even the class itself FWIW) ?
Defining the class "members" at the class top-level is mostly a static languages thing, where "objects" are mainly (technically) structs (C style structs, or Pascal style records if you prefer) with a statically defined memory structure.
Python is a dynamic language, which instead uses dicts as supporting data structure, so someobj.attribute is usually (minus computed attributes etc) resolved as someobj.__dict__["attribute"] (and someobj.attribute = value as someobj.__dict__["attribute"] = value).
So 1/ it doesn't NEED to have a fixed, explicitely defined data structure, and 2/ yet it DOES need to have an instance at end to set an attribute on it.
Note that you can force a class to use a fixed memory structure (instead of a plain dict) using slots, but you will still need to set the values from within a method (canonically the __init__, which exists for this very reason: initializing the instance's attributes).

Discovering dependency API in a python class

In the following class:
class SomeClass(object):
def __init__(self, somedependency):
self._somedependency = somedependency
def do_something(self):
self._field = _somedependency.get_something()
Is it possible to "know" that somedependency has a function called get_something() at runtime just as you would know the public methods and properties of a constructor parameter in C# at compile time?
EDIT: I'd like to get the somedependency's members and create a new type with those members, so what I need to perform an action such as "I'm calling methods and properties of this constructor parameter in the calling class. Give me all those methods and parameters as these are seen in the calling class". As I don't know the type of the constructor parameter I cannot determine this in a way you can do in static languages.
If you just want to verify that a known method exists, use func = getattr(_somedependency, 'get_something'); if func: func().
If you want more inspection like what methods a class or instance has, check out the built in inspect module.

Is there any particular reason why this syntax is used for instantiating a class?

I was wondering if anyone knew of a particular reason (other than purely stylistic) why the following languages these syntaxes to initiate a class?
Python:
class MyClass:
def __init__(self):
x = MyClass()
Ruby:
class AnotherClass
def initialize()
end
end
x = AnotherClass.new()
I can't understand why the syntax used for the constructor and the syntax used to actually get an instance of the class are so different. Sure, I know it doesn't really make a difference but, for example, in ruby what's wrong with making the constructor "new()"?
When you are creating an object of a class, you are doing more than just initializing it. You are allocating the memory for it, then initializing it, then returning it.
Note also that in Ruby, new() is a class method, while initialize() is an instance method. If you simply overrode new(), you would have to create the object first, then operate on that object, and return it, rather than the simpler initialize() where you can just refer to self, as the object has already been created for you by the built-in new() (or in Ruby, leave self off as it's implied).
In Objective-C, you can actually see what's going on a little more clearly (but more verbosely) because you need to do the allocation and initialization separately, since Objective-C can't pass argument lists from the allocation method to the initialization one:
[[MyClass alloc] initWithFoo: 1 bar: 2];
Actually in Python the constructor is __new__(), while __init__() is instance initializer.
__new__() is static class method, thus it has to be called first, as a first parameter (usually named cls or klass) it gets the class . It creates object instance, which is then passed to __init__() as first parameter (usually named self), along with all the rest of __new__'s parameters.
This is useful because in Python, a constructor is just another function. For example, I've done this several times:
def ClassThatShouldntBeDirectlyInstantiated():
return _classThatShouldntBeDirectlyInstantiated()
class _classThatShouldntBeDirectlyInstantiated(object):
...
Of course, that's a contrived example, but you get the idea. Essentially, most people that use your class will probably think of ClassThatShouldntBeDirectlyInstantiated as your class, and there's no need to let them think otherwise. Doing things this way, all you have to do is document the factory function as the class it instantiates and not confuse anyone using the class.
In a language like C# or Java, I sometimes find it annoying to make classes like this because it can be difficult to determine whether you should use the constructor or some factory function. I'm not sure if this is also the case in Ruby though.

Categories