How to access class module from object instance? - python

I want to access module-level variables of the module that defines the class the instance is derived from. I only have the instance to work from. I tried self.__class__.__module__[<some var>] but unlike the __class__ attribute which returns the class object, __module__ just returns a string name, not the module object itself. How can I get the module object in this situation?

The __module__ attribute can be used as a key in the sys.modules dictionary:
import sys
class_module = sys.modules[instance.__class__.__module__]

Related

Can staticmethod be imported?

there are many examples of staticmethod in a class with caller in one file. this works fine. but i have tried to save the class with staticmethod in a single file and import it from caller. this then throws the error "AttributeError: 'module' object has no attribute methodname"
i am using python2.7.
used exact example from Static methods in Python?
import MyClass
# belwo class is saved in a saparate file named MyClass.py
# class MyClass(object):
# #staticmethod
# def the_static_method(x):
# print(x)
MyClass.the_static_method(2) # outputs 2
# if via import, we have the error: AttributeError: 'module' object has no attribute 'the_static_method'
In your example, since the name of the python file (MyClass.py) is the same as the class name, Python will assume you are referring to the module MyClass(which is your file) instead of the class MyClass. One suggestion is to change your first line import MyClass to from MyClass import MyClass. Then it should work. It's generally better to follow the Python naming convention recommended here https://softwareengineering.stackexchange.com/questions/308972/python-file-naming-convention

Iterating over built-in atributes of foo.py module. Got an error

I'm doing a loop: "for atribute in dir(foo):"
however i can not use 'atribute' variable as it were built-in atributes of foo. Why is that?
When
print(__name__) # <class 'str'>
and
for atribute in dir(foo):
print(atribute) # is <class 'str'> too
...so why I get an error as below?
import foo
for atribute in dir(foo):
print(foo.atribute)
#AttributeError: module 'foo' has no attribute 'atribute'
When you're trying to print foo.method, you are trying to lookup a method attribute of the foo object. That name is unrelated to the method variable you already have in your local namespace. To lookup an attribute who's name is in the method variable, use getattr:
for method in dir(foo):
print(getattr(foo, method))
The method from you for statement, differs from the method of foo. Imagine having a list; when you iterate over it with the variable x you obviously can't do list.x. In some way or another, you are doing exactly this. A way to get an attribute from a string is the getattr function. In your case it would be used like so:
import foo
for method in dir(foo):
print(getattr(foo, method))
Here is a usefull link about this function.
In the for loop, method is a name which refers to different object on each iteration.
When you do foo.method, you're trying to get an attribute of module foo with literal name method, which is not the name method that you're using in the loop. If you use a different attribute e.g. foo.bar, it would be more clear to you.
Now, presumably you want to get the attribute that the loop variable method refers to, if so you need getattr which gets attribute values from string attribute names.
dir returns the attributes as a list of strings, so on each iteration you get the value of the attribute string object referred by the name method:
for method in dir(foo):
print(getattr(foo, method))

class members also creates instance members in python

It seems that python class members also are "secretly" copied to instance members, I have never heard of this. Is this described somewhere?
Here is a small example I did to investigate this (python 3.6.7 ubuntu 18:04).
class A:
a = 'hello' # class member
def __init__(self):
print(self.a) # a has also become a instance member
self.a = 'Hi' # change the instance member of a
print(A.a) # class member a unchanged
a = A()
This is not at all a "secret" copy. It is the intended behaviour and for example discussed here in the official reference (3.2. The standard type hierarchy: "Class instances"):
A class instance is created by calling a class object (see above). A class instance has a namespace implemented as a dictionary which is the first place in which attribute references are searched. When an attribute is not found there, and the instance’s class has an attribute by that name, the search continues with the class attributes. [...]
By creating an entry for the attribute in the class instance's dictionary, you shadow the class's attribute entry.
Let's walk through your example step-by-step:
def __init__(self):
print(self.a) # (1.)
self.a = 'Hi' # (2.)
print(A.a) # (3.)
Attribute lookup starts at the instance's attribute dict. No matching attribute is found, hence, lookup continues at the class's attribute dict. A matching attribute, a = 'hello', is found.
An explicit assignment using the class instance creates a new attribute entry of name a in the class instance's attribute dict. Consequently, this attribute is unique to the class instance.
The class attribute remains unchanged because it resides in an entirely different dict, the attribute dict of the class rather than the instance.

How to define custom Object name for instance of created class?

Python everything is object. We do find the name of the object we are using type() builtin method.
If I create class as follows
class Sample:
pass
a=Sample()
type(a)
returns as __main__.Sample
Here I want it to be print the name of object of my choice, how do I do that.
Ex: type({})
return Dict
I want to name object instance of my custom class
One can use module to replace main in type of the class instance,
i.e
class Sample():
__module__='custom'
type(Sample()) returns custom.Sample
I think I figured it out with existing python packages,
i.e
in pandas, it has DataFrame class or object when you define variable to this object and type of it returns pandas.core.frame.DataFrame. Here DataFrame is the class and pandas.core.frame is the module name of the class
so one can define his object name with replacing __main__ only i.e as shown below
class Sample():
__module__='Custom'
a=Sample()
print(type(a))
prints==> < class Custom.Sample>

Is there any a pure clean class which support getattr and setattr in Python?

I use a Context class:
class Context(object):
...
So I can use this class to define a object which support getattr and setattr. I want to use the object to communicate between some threads.
However I think it is stupid to let the user define such a class. So I want to find out is there any a primitive type or a class from the standard library which support getattr and setattr.
I have tried the object class, but the object of it can not set attribute:
a = object()
a.b = 1
class C(object):
...
c = C()
c.d = 1
I can set c.d = 1, but a.b complains 'object' object has no attribute 'b'。
Try types.SimpleNamespace:
A simple object subclass that provides attribute access to its namespace, as well as a meaningful repr.
Unlike object, with SimpleNamespace you can add and remove attributes.

Categories

Resources