I can make a synthetic class cls1 that inherits from cls.
>>> class cls(object):
... def func(self,arg):
... print 'func',arg
>>> def func1(self):
... print "func 1 of cls1"
>>> def func2(self):
... print "func2 of cls1"
>>> d=dict(func1=func1,func2=func2)
>>> cls1=type('cls1',(cls,),d)
Everything works as expected:
>>> obj=cls1()
>>> obj.func(7)
func 7
I can also replace cls1 with FOO:
>>> cls1=type('FOO',(cls,),d)
that gives me:
'cls1': <class '__main__.FOO'>,
Does this (changing __name__ variable) alter the behavior of cls1 and how (everything still works fine)?
You're just changing the name of your class, so it should matter only if you rely on the name somehow:
>>> type(obj)
__main__.FOO
>>> isintance(obj, cls1)
True
That works fine, but what about pickling (that I think rely on the name) ?
For example, before the name change, you can pickle obj without any problem. You can't afterwards.
PicklingError: Can't pickle <class '__main__.FOO'>: it's not found as __main__.FOO
Related
x = 60
y = 300
platform_name = "Platform"
platform_parts = 1
%s.Platform(x,y, "edge_left") % platform_name+"_"+str(platform_parts)
This is supposed to create a platform from my Platform class with the name Platform_1, but instead it gives a syntax error, pointing at the %s part. Does anyone know what I'm doing wrong here and how it's supposed to be?
You can make a class object with a variable name by using the type builtin.
>>> class Foo: pass # Normal class declaration.
>>> Foo # See how it's printed.
<class '__main__.Foo'>
>>> Foo_1 = Foo() # Instantiation and assignment.
>>> Foo_1
<__main__.Foo object at 0x0000029B7FF5A240>
>>> name = 'Bar' # Name in a string variable.
>>> globals()[name] = type(name, (), {}) # Dynamic class name from variable.
>>> Bar
<class '__main__.Bar'>
>>> Bar()
<__main__.Bar object at 0x0000029B7FF5AA90>
You can also run code in strings using exec. Using exec is usually frowned upon because there's almost always a better way, but beginners often don't know how. But this technique is even used in the standard library e.g. in namedtuple.
>>> name = 'Baz'
>>> codestring = f'''
class {name}: pass
'''
>>> codestring
'\nclass Baz: pass\n'
>>> print(codestring)
class Baz: pass
>>> exec(codestring, globals())
>>> Baz
<class '__main__.Baz'>
If you're just trying to assign an instance to a dynamic name,
globals()[platform_name+"_"+str(platform_parts)] = Platform(x,y, "edge_left")
Which would make the global variable named Platform_1 with the Platform instance.
It looks like there is a function as well as a class associated with the name cv2.VideoCapture.
Is it possible for a class and a function that share a common name?
My guess is that at this moment cv2.VideoCapture represents a class and a function as well.
>>>import cv2
>>>print(cv2.VideoCapture)
<built-in function VideoCapture>
>>>camera = cv2.VideoCapture(0)
>>>print(type(camera))
<class 'cv2.VideoCapture'>
All depends on what you call "name"...
>>> class Foo(object):
... pass
...
>>> _Foo = Foo
>>> def Foo():
... return _Foo()
...
>>> f = Foo()
>>> print(Foo)
<function Foo at 0x7f74a5fec8c0>
>>> print(type(f))
<class '__main__.Foo'>
>>>
As you can see, you here have a function exposed as Foo and having it's __name__ == "Foo", and a class exposed as _Foo but having __name__ == "Foo" too.
To answer your question: you cannot have the same name (=> variable) bound to more than one object at a given time in a given namespace. But you can have has many objects has you want having the same value for a .__name__ attribute.
I have not checked the OpenCV source code in order to check out what or why is going on in this specific case, but in theory this can be possible if your function returns an instance of a class with the same name.
consider the file cv2.py with the following content
def VideoCapture(_):
class VideoCapture(object):
pass
return VideoCapture()
usage:
>>> import cv2
>>> cv2.VideoCapture
<function VideoCapture at 0x7f70d36069b0>
>>>
>>> camera = cv2.VideoCapture(0)
>>> type(camera)
<class 'cv2.VideoCapture'>
To get a string representation of a class name we can use obj.__class__.__name__ is it possible to overload these methods so that I can return my string instead of the actual class name?
Let's try! (Yes, this works):
>>> class Foo(object):
... pass
...
>>> obj = Foo()
>>> obj.__class__.__name__ = 'Bar'
>>> obj
<__main__.Bar object at 0x7fae8ba3af90>
>>> obj.__class__
<class '__main__.Bar'>
You could also have just done Foo.__name__ = 'Bar', I used obj.__class__.__name__ to be consistent with your question.
Yep.
class A:
def __init__(self):
self.__class__.__name__ = 'B'
But this seems like a bad idea.
You can do this:
>>> class Foo(object):
... def __init__(self):
... self.__class__.__name__ = "Bar"
...
>>> print Foo().__class__.__name__
Bar
Or you can make your own double underscore attribute.
>>> class Foo(object):
... __name__ = "Bar"
...
>>> print Foo().__name__
Bar
But why would you want to do this? I don't see any possible use for this. BTW, I realize this is not the same as __class__.__name__, but I don't think changing __class__.__name__ is generally a good idea.
I have a two part question.
>>> class One(object):
... pass
...
>>> class Two(object):
... pass
...
>>> def digest(constr):
... c = apply(constr)
... print c.__class__.__name__
... print constr.__class__.__name__
...
>>> digest(Two)
Two
type
How would one create object 'Two'? Neither constr() or c() work; and it seems that apply turns it into a type.
What happens when you pass a class rather and an instance into a method?
Classes are high level objects, so you can simply pass them like this:
def createMyClass ( myClass ):
obj = myClass()
return obj
class A ( object ):
pass
>>> x = createMyClass( A )
>>> type( x )
<class '__main__.A'>
How would one create object 'Two'?
Neither constr() or c() work; and it
seems that apply turns it into a
type.
The above comment was made in regards to this code:
>>> def digest(constr):
... c = apply(constr)
... print c.__class__.__name__
... print constr.__class__.__name__
apply (deprecated: see #pyfunc's answer) certainly does not turn the class Two into a type: It already is one.
>>> class Two(object): pass
...
>>> type(Two)
<type 'type'>
Classes are first class objects: they're instances of type. This makes sense if you look at the next example.
>>> two = Two()
>>> type(two)
<class '__main__.Two'>
You can see that a class very clearly functions as a type because it can be returned from type. Here's another example.
>>> Three = type('Three', (Two, ), {'foo': 'bar'})
>>> type(Three)
<type 'type'>
>>> three = Three()
>>> type(three)
<class '__main__.Three'>
You can see that type is a class that can be instantiated. Its constructor takes three arguments: the name of the class, a tuple of base classes and a dictionary containing the class attributes. It returns a new type aka class.
As to your final question,
What happens when you pass a class
rather and an instance into a method?
You're going to have to be more specific. Classes are just instances of type and so are first class objects. Asking what happens if I pass a class into a method is like asking what happens if I pass an integer into a method: It depends entirely on what the method is expecting.
Just another one example:
def InstanceFactory(classname):
cls = globals()[classname]
return cls()
class A(object):
def start(self):
print "a.start"
class B(object):
def start(self):
print "b.start"
InstanceFactory("A").start()
InstanceFactory("B").start()
If the class belongs to another module:
def InstanceFactory(modulename, classname):
if '.' in modulename:
raise ValueError, "can't handle dotted modules yet"
mod = __import__(modulename)
cls = getattr(mod, classname]
return cls()
I am confused though. Wasn't apply() deprecated since 2.3
http://www.python.org/dev/peps/pep-0290/
We don't need this any more.
apply(f, args, kwds) --> f(*args, **kwds)
Others have been moved / considered deprecated in modern usage:
buffer()
coerce()
and intern()
Simply use : Classname() to create an object.
Given an instance of some class in Python, it would be useful to be able to determine which line of source code defined each method and property (e.g. to implement 1). For example, given a module ab.py
class A(object):
z = 1
q = 2
def y(self): pass
def x(self): pass
class B(A):
q = 4
def x(self): pass
def w(self): pass
define a function whither(class_, attribute) returning a tuple containing the filename, class, and line in the source code that defined or subclassed attribute. This means the definition in the class body, not the latest assignment due to overeager dynamism. It's fine if it returns 'unknown' for some attributes.
>>> a = A()
>>> b = B()
>>> b.spigot = 'brass'
>>> whither(a, 'z')
("ab.py", <class 'a.A'>, [line] 2)
>>> whither(b, 'q')
("ab.py", <class 'a.B'>, 8)
>>> whither(b, 'x')
("ab.py", <class 'a.B'>, 9)
>>> whither(b, 'spigot')
("Attribute 'spigot' is a data attribute")
I want to use this while introspecting Plone, where every object has hundreds of methods and it would be really useful to sort through them organized by class and not just alphabetically.
Of course, in Python you can't always reasonably know, but it would be nice to get good answers in the common case of mostly-static code.
You are looking for the undocumented function inspect.classify_class_attrs(cls). Pass it a class and it will return a list of tuples ('name', 'kind' e.g. 'method' or 'data', defining class, property). If you need information on absolutely everything in a specific instance you'll have to do additional work.
Example:
>>> import inspect
>>> import pprint
>>> import calendar
>>>
>>> hc = calendar.HTMLCalendar()
>>> hc.__class__.pathos = None
>>> calendar.Calendar.phobos = None
>>> pprint.pprint(inspect.classify_class_attrs(hc.__class__))
[...
('__doc__',
'data',
<class 'calendar.HTMLCalendar'>,
'\n This calendar returns complete HTML pages.\n '),
...
('__new__',
'data',
<type 'object'>,
<built-in method __new__ of type object at 0x814fac0>),
...
('cssclasses',
'data',
<class 'calendar.HTMLCalendar'>,
['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']),
('firstweekday',
'property',
<class 'calendar.Calendar'>,
<property object at 0x98b8c34>),
('formatday',
'method',
<class 'calendar.HTMLCalendar'>,
<function formatday at 0x98b7bc4>),
...
('pathos', 'data', <class 'calendar.HTMLCalendar'>, None),
('phobos', 'data', <class 'calendar.Calendar'>, None),
...
]
This is more-or-less impossible without static analysis, and even then, it won't always work. You can get the line where a function was defined and in which file by examining its code object, but beyond that, there's not much you can do. The inspect module can help with this. So:
import ab
a = ab.A()
meth = a.x
# So, now we have the method.
func = meth.im_func
# And the function from the method.
code = func.func_code
# And the code from the function!
print code.co_firstlineno, code.co_filename
# Or:
import inspect
print inspect.getsource(meth), inspect.getfile(meth)
But consider:
def some_method(self):
pass
ab.A.some_method = some_method
ab.A.some_class_attribute = None
Or worse:
some_cls = ab.A
some_string_var = 'another_instance_attribute'
setattr(some_cls, some_string_var, None)
Especially in the latter case, what do you want or expect to get?
You are looking for the inspect module, specifically inspect.getsourcefile() and inspect.getsourcelines(). For example
a.py:
class Hello(object):
def say(self):
print 1
>>> from a import Hello
>>> hi = Hello()
>>> inspect.getsourcefile(hi.say)
a.py
>>> inspect.getsourcelines(A, foo)
([' def say(self):\n print 1\n'], 2)
Given the dynamic nature of Python, doing this for more complicated situations may simply not be possible...