hasattr on class names - python

hasattr documentation says that it takes an object and an attribute name and lets you know if that attribute exists on that object.
I have discovered that it seems to work on class names too (i.e. not an instance object).
Something like:
class A:
def Attr1(self):
pass
> hasattr(A, 'Attr1')
True
>
I would like to use this to make some test code easier to write, but don't want to be bitten later in case this is a side effect of the implementation and not really intended.
Please don't ask to see the test code to see if I can do something else, as that is not really the question.
Is there any official python stance on this? I presume the object referred to, in the documentation is talking about an instance object.
I tried googling (and looking at some questions in StackOverflow), but didn't seem to find anything.

The fact that it works on a class in addition to an instance is intentional. In fact, hasattr should work on any object that you pass to it. Basically, it does something like this:
def hasattr(obj, attribute):
try:
getattr(obj, attribute)
except:
return False
return True
You can rely on that and not be afraid of getting bit by a change later. Note, there is some discussion on python-dev about hasattr being broken by design. The gist of it is that hasattr catches any exception which can be misleading.
Note that, in python classes are themselves instances of type.
>>> class Foo(object):
... pass
...
>>> type(Foo)
<type 'type'>
so everything is an instance of something1.
1type is an instance of itself which is something that would be impossible to do in pure python...

I do not have a reference on the "official Python stance" at hand, but this is perfectly normal and intentional. Remember that
instance_of_SomeClass.some_method(parameters, ...)
is in fact syntactic sugar for
SomeClass.some_method(instance_of_SomeClass, parameters, ...)
i.e. those methods are in fact attributes of the class and thus can be tested with hasattr.

Just want a reference (even for the sentence that everything is an object...)
I recommend you to read this chapter (or the whole book if you have the time):
http://www.diveintopython.net/getting_to_know_python/everything_is_an_object.html

Related

don't understand explanations for Python descriptors cannot be instance variables

I was searching the rationale about descriptors cannot be instance variables, and found this post. In #nneonneo's answer he quoted an answer from Python mail list. I put the quote here.
The answer listed two reasons that I have doubts: for the first reason, it said
if the "M" descriptor is defined by some instances rather than by the class, then knowing that the object "reg" is an instance of Register does not tell me anything about whether "reg.M" is a valid attribute or an error.
But my question is that if "M" descriptor was defined in __init__(), how come it is defined by some instances? Every instance should have an "M" descritor attribute after initialization. Then "reg.M" should always be valid attribute.
for the second reason, the ObjectHolder example,
Instead of treating "holder.obj" as a simple data
attribute, it would start invoking the descriptor protocol on accesses
to "holder.obj" and ultimately redirect them to the non-existent and
meaningless "holder.foo" attribute, which is certainly not what the
author of the class intended.
the original question is about why descriptors cannot be instance variables, this second reason just uses existing mechanism to explain a hypothetical situation. I mean if descriptors are going to be valid as instance variables, there should be some checks and transforms coming along to make it work. I dont' think you can use the mechanism for "descriptors as class variables" to explain "descriptors as instance variables", especially the latter does not exist for now and maybe can be developed to valid in future.
Thanks,
I cannot stress this enough:
The behavior is by design. [1]
That's it. This is they way the language was implemented and why decorators work better with classes is a consequence of that. Resources you provided go into detail why decorators on classes work better, so I will no repeat myself.
Regarding your questions...
If "M" descriptor was defined in init(), how come it is defined by some instances?
It is not, you're right. Ian was presententing the point that, in general, per-instance initialisation based on some conditions may not quarantee that the "reg.M" will not raise AttributeError. This is not the case with class decorators. If you're always initializting in the __init__ then you're fine. Until, for example, someone overrides your __init__ or does del on the attribute. With class, you only need to watch the class.
Instead of treating "holder.obj" as a simple data attribute, it would start invoking the descriptor protocol on accesses to "holder.obj" and ultimately redirect them to the non-existent and meaningless "holder.foo" attribute, which is certainly not what the author of the class intended.
Ok, let's assume we have an object:
>>> a = property(lambda o: o.eggs)
>>> a
<property object at 0x7f9db318a838>
This is perfectly legal, right? Ok, what if I want to store it on an instance of some class? I would do:
>>> class Foo: pass
...
>>> foo = Foo()
>>> foo.a = a
>>> foo.a
<property object at 0x7f9db318a838>
Ok, so this works, cool!
The problem with instance decorators here is that this would not be possible if Python applied decorator protocol to a. Typing foo.a would make it try to evaluate eggs yielding AttributeError. Therefore, in order to have two behaviours possible, the decorator protocol is not invoked on the instance foo.
I hope this clears it up a bit. :)
[1] https://mail.python.org/pipermail/python-list/2012-January/618572.html
[2] https://mail.python.org/pipermail/python-list/2012-January/618570.html

Do Python objects originate from a common parent class?

Everything in Python is an object, and almost everything has attributes and methods. Now, according to Object Oriented Programming, every object created in Python must be an instance of a common parent class. However, this logic just doesn't make sense to me.
Can someone clear this up for me?
according to Object Oriented Programming, every object created in Python must be an instance of a common parent class
This is not true. It happens that, in Objective-C, Java (and maybe C# too?), things tend to derive from a single superclass, but this is an implementation detail - not a fundamental of OO design.
OO design just needs a common-enough method to find the implementation of a method you wish to call on the object on which you wish to call it. This is usually fundamental to how the language works (C++, C#, Java, Objective-C, Python, etc all do it their own way that makes sense for their language).
In C++, this is done for static types by the linker and for dynamic types (through virtual inheritance) by a vector table -- no need for a common base class.
In Objective-C, this is done by looking up something in a hash-map on the object's class's structure, then calling a specific method to get the signature of the desired method. This code is nuanced, so everything generally derives from a single, common base-class.
Python technically shouldn't require this, but I think they've made an implementation choice to make everything be a class and every class derive from a common base class.
In Python, all derive from the class type
this is why, whem creating a metaclass, we subclass type
class Meta(type):
def __new__(cls, name, bases, attrs):
<logic here>
class Foo(object):
__metaclass__ = Meta
Also:
type(object) -> type
type(type) -> type
DynamicClass = type('DynamicClass', (Foo,), {'a': 1, 'b':2})
dyn = DynamicClass()
type(dyn) -> Foo
etc, etc
Well,
li = [1, 2, 3, 4]
class A:
def __init__(self):
pass
a = A()
print isinstance(a, object)
print isinstance(li, object)
print isinstance(5, object)
>> True
>> True
>> True
At some point in my life when I was confused about this, the following short tutorial helped me:
python objects and types
But if your confusion is more basic than this, then maybe you want to clarify which part of "everything is an object" you're having trouble with.
The common parent class in Python is object. In fact, although it's not mandatory in some versions, you should always declare your classes like this:
class MyClass(object):
...

Read only python attribute? Can't print object

I have an instance of a cx_Oracle.Connection called x and I'm trying to print x.clientinfo or x.module and getting:
attribute 'module' of 'cx_Oracle.Connection' objects is not readable
(What's weird is that I can do print x.username)
I can still do dir(x) with success and I don't have time to look at the source code of cx_Oracle (lots of it implemented in C) so I'm wondering how the implementer was able to do this? Was it by rolling descriptors? or something related to __getitem__? What would be the motivation for this?
You can do this pretty easily in Python with a custom descriptor.
Look at the Descriptor Example in the HOWTO. If you just change the __get__ method to raise an AttributeError… that's it. We might as well rename it and strip out the logging stuff to make it simpler.
class WriteOnly(object):
"""A data descriptor that can't be read.
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
raise AttributeError("No peeking at attribute '{}'!".format(self.name))
def __set__(self, obj, val):
self.val = val
class MyClass(object):
x = WriteOnly(0, 'x')
m = MyClass()
m.x = 20 # works
print(m.x) # raises AttributeError
Note that in 2.x, if you forget the (object) and create a classic class, descriptors won't work. (I believe descriptors themselves can actually be classic classes… but don't do that.) In 3.x, there are no classic classes, so that's not a problem.
So, if the value is write-only, how would you ever read it?
Well, this toy example is useless. But you could, e.g., set some private attribute on obj rather than on yourself, at which point code that knows where the data are stored can find it, but casual introspection can't.
But you don't even need descriptors. If you want an attribute that's write-only no matter what class you attach it to, that's one thing, but if you just want to block read access to certain members of a particular class, there's an easier way:
class MyClass(object):
def __getattribute__(self, name):
if name in ('x', 'y', 'z'):
raise AttributeError("No! Bad user! You cannot see my '{}'!".format(name))
return super().__getattribute__(self, name)
m = MyClass()
m.x = 20
m.x # same exception
For more details, see the __getattr__ and __getattribute__ documentation from the data model chapter in the docs.
In 2.x, if you leave the (object) off and create a classic class, the rules for attribute lookup are completely different, and not completely documented, and you really don't want to learn them unless you're planning to spend a lot of time in the 90s, so… don't do that. Also, 2.x will obviously need the 2.x-style explicit super call instead of the 3.x-style magic super().
From the C API side, you've got most of the same hooks, but they're a bit different. See PyTypeObjects for details, but basically:
tp_getset lets you automatically build descriptors out of getter and setter functions, which is similar to #property but not identical.
tp_descr_get and tp_descr_set are for building descriptors separately.
tp_getattro and tp_setattro are similar to __getattr__ and __setattr__, except that the rules for when they get called are a little different, and you typically call PyObject_GenericGetAttr instead of delegating to super() when you know you have no base classes that need to hook attribute access.
Still, why would you do that?
Personally, I've done stuff like this to learn more about the Python data model and descriptors, but that's hardly a reason to put it in a published library.
I'm guessing that more often than not, someone does it because they're trying to force a mistaken notion of OO encapsulation (based on the traditional C++ model) on Python—or, worse, trying to build Java-style security-by-encapsulation (which doesn't work without a secure class loader and all that comes with it).
But there could be cases where there's some generic code that uses these objects via introspection, and "tricking" that code could be useful in a way that trying to trick human users isn't. For example, imagine a serialization library that tried to pickle or JSON-ify or whatever all of the attributes. You could easily write it ignore non-readable attributes. (Of course you could just as easily make it, say, ignore attributes prefixed with a _…)
As for why cx_Oracle did it… I've never even looked at it, so I have no idea.

What is the python way to declare an existing object as an instance of a class?

I've been using AS3 before, and liked its grammar, such as the keyword as.
For example, if I type (cat as Animal) and press . in an editor, the editor will be smart enough to offer me code hinting for the class Animal no matter what type cat actually is, and the code describes itself well.
Python is a beautiful language. How am I suppose to do the above in Python?
If you were to translate this literally, you'd end up with
cat if isinstance(cat, Animal) else None
However, that's not a common idiom.
How am I suppose to do the above in Python?
I'd say you're not supposed to do this in Python in general, especially not for documentation purposes.
In Python, object is created to be an instance of a class, you cannot declare an existing object to be an instance of a class. Since the class have __init__ method, the initialization is essence for a class instance.
You're looking for polymorphic behavior in Python.
It doesn't really work the same way as in other languages like Java - what we have is isinstance().
Which leads to
class FirstObject(object):
#someStuff
class SecondObject(FirstObject):
#someStuff
>> someObject = SecondObject()
>> isinstance(someObject, SecondObject)
>> true
and the same for
>> isinstance(someObject, FirstObject)
>> true
How this works then with the dot notation is something called the Method Resolution Order, or MRO where it looks up methods "left to right" in the class declaration.
This feature isn't available in the shell ATM but is scheduled for an upcoming release of Python.
When writing this I found this SO question - rendering my answer moot.
You can, in some circumstances, change the class of an existing instance of an object by setting its __class__ attribute:
class Foo(object):
#property
def myname(self):
return "I'm a Foo"
class Bar(object):
#property
def myname(self):
return "I'm a Bar"
thing = Foo()
print thing.myname
thing.__class__ = Bar
print thing.myname
I think this only works for members of "new-style" Python classes derived from object.
You are looking for a way to inspect the class of an instance.
isinstance(instance, class) is a good choice. It tells you whether the instance is of a class or is an instance of a subclass of the class.
In other way, you can use instance.__class__ to see the exact class the instance is and class.__bases__ to see the superclasses of the class.
For built-in types like generator or function, you can use inspect module.
Names in python do not get a type. So there is no need to do the cast and in return determine the type of an instance is a good choice.
As for the hints feature, it is a feature of editors or IDEs, not Python.
Python has no type declarations. If cat is an Animal, you can just use it as an Animal, and it'll work. You don't have to cast it to an expression of type Animal, like you would in a statically typed language. Unfortunately, this also means it's hard to provide code completion, since for all your IDE knows, cat could be a Nacho.

How does extending classes (Monkey Patching) work in Python?

class Foo(object):
pass
foo = Foo()
def bar(self):
print 'bar'
Foo.bar = bar
foo.bar() #bar
Coming from JavaScript, if a "class" prototype was augmented with a certain attribute. It is known that all instances of that "class" would have that attribute in its prototype chain, hence no modifications has to be done on any of its instances or "sub-classes".
In that sense, how can a Class-based language like Python achieve Monkey patching?
The real question is, how can it not? In Python, classes are first-class objects in their own right. Attribute access on instances of a class is resolved by looking up attributes on the instance, and then the class, and then the parent classes (in the method resolution order.) These lookups are all done at runtime (as is everything in Python.) If you add an attribute to a class after you create an instance, the instance will still "see" the new attribute, simply because nothing prevents it.
In other words, it works because Python doesn't cache attributes (unless your code does), because it doesn't use negative caching or shadowclasses or any of the optimization techniques that would inhibit it (or, when Python implementations do, they take into account the class might change) and because everything is runtime.
I just read through a bunch of documentation, and as far as I can tell, the whole story of how foo.bar is resolved, is as follows:
Can we find foo.__getattribute__ by the following process? If so, use the result of foo.__getattribute__('bar').
(Looking up __getattribute__ will not cause infinite recursion, but the implementation of it might.)
(In reality, we will always find __getattribute__ in new-style objects, as a default implementation is provided in object - but that implementation is of the following process. ;) )
(If we define a __getattribute__ method in Foo, and access foo.__getattribute__, foo.__getattribute__('__getattribute__') will be called! But this does not imply infinite recursion - if you are careful ;) )
Is bar a "special" name for an attribute provided by the Python runtime (e.g. __dict__, __class__, __bases__, __mro__)? If so, use that. (As far as I can tell, __getattribute__ falls into this category, which avoids infinite recursion.)
Is bar in the foo.__dict__ dict? If so, use foo.__dict__['bar'].
Does foo.__mro__ exist (i.e., is foo actually a class)? If so,
For each base-class base in foo.__mro__[1:]:
(Note that the first one will be foo itself, which we already searched.)
Is bar in base.__dict__? If so:
Let x be base.__dict__['bar'].
Can we find (again, recursively, but it won't cause a problem) x.__get__?
If so, use x.__get__(foo, foo.__class__).
(Note that the function bar is, itself, an object, and the Python compiler automatically gives functions a __get__ attribute which is designed to be used this way.)
Otherwise, use x.
For each base-class base of foo.__class__.__mro__:
(Note that this recursion is not a problem: those attributes should always exist, and fall into the "provided by the Python runtime" case. foo.__class__.__mro__[0] will always be foo.__class__, i.e. Foo in our example.)
(Note that we do this even if foo.__mro__ exists. This is because classes have a class, too: its name is type, and it provides, among other things, the method used to calculate __mro__ attributes in the first place.)
Is bar in base.__dict__? If so:
Let x be base.__dict__['bar'].
Can we find (again, recursively, but it won't cause a problem) x.__get__?
If so, use x.__get__(foo, foo.__class__).
(Note that the function bar is, itself, an object, and the Python compiler automatically gives functions a __get__ attribute which is designed to be used this way.)
Otherwise, use x.
If we still haven't found something to use: can we find foo.__getattr__ by the preceding process? If so, use the result of foo.__getattr__('bar').
If everything failed, raise AttributeError.
bar.__get__ is not really a function - it's a "method-wrapper" - but you can imagine it being implemented vaguely like this:
# Somewhere in the Python internals
class __method_wrapper(object):
def __init__(self, func):
self.func = func
def __call__(self, obj, cls):
return lambda *args, **kwargs: func(obj, *args, **kwargs)
# Except it actually returns a "bound method" object
# that uses cls for its __repr__
# and there is a __repr__ for the method_wrapper that I *think*
# uses the hashcode of the underlying function, rather than of itself,
# but I'm not sure.
# Automatically done after compiling bar
bar.__get__ = __method_wrapper(bar)
The "binding" that happens within the __get__ automatically attached to bar (called a descriptor), by the way, is more or less the reason why you have to specify self parameters explicitly for Python methods. In Javascript, this itself is magical; in Python, it is merely the process of binding things to self that is magical. ;)
And yes, you can explicitly set a __get__ method on your own objects and have it do special things when you set a class attribute to an instance of the object and then access it from an instance of that other class. Python is extremely reflective. :) But if you want to learn how to do that, and get a really full understanding of the situation, you have a lot of reading to do. ;)

Categories

Resources