What is the difference between __get__() and __getattr__() in Python? I come from a PHP background, where there is only __get(). When should I use which function?
I've been trying to figure this out for a while. I see plenty of questions like this one, asking about the difference between __getattr__() and __getattribute__(), though.
First an foremost, PHP does not have an equivalent to Python's __get__() – not even close! What you are looking for is most definitely __getattr__().
I come from a PHP background, where there is only __get__
PHP has a magic method called __get(), which is invoked whenever you are trying to access a property that does not exist.
A short list of non-equivalents
First, let's clear some things up:
PHP does not have an equivalent to Python's __get__()
PHP does not have an equivalent to Python's __getattr__()
PHP does not have an equivalent to Python's __getattribute__()
Python does not have an equivalent to PHP's __get()
(And for all setter methods respectively.)
Contrary to Achim's assumption, __get() does not do the same as Python's __getattr__()!
Python does not distinguish between methods and properties, but PHP does, which is why PHP has a second method: __call().
__call() is executed whenever you try to invoke a method on an object that does not exist. Python does not have an equivalent for this, because a method is simply an object (attribute) that is callable.
An example in PHP:
<?php
$obj = new stdClass();
($obj->test)();
In Python, this would fail with an AttributeError. In PHP, however, this does not even compile:
Parse error: syntax error, unexpected '(' on line 4
Compare this to Python:
obj.method()
# is eqvuivalent to:
(obj.method)()
This is an important difference. We conclude that the way PHP and Python think about calling methods are completely different.
PHP's "call awareness"
PHP's obj knows that you call a method
you get to handle calls to non-existing methods explicitly on the object you call on
this is because PHP's expression model is very inconsistent (PHP 5.4 is a small step forward though)
but Python's obj does not.
This makes it possible for PHP to have obj.does_not_exist to evaluate to 3, but obj.does_not_exist() to 5.
To my knowledge, it's impossible to do so in Python. (This would allow us to describe PHP's inconsistency as a feature.)
Thus, we get to extend our "not equivalent"-list by one bullet point:
Python does not have an equivalent to PHP's __call()/__callStatic()
Summing it up
PHP provides two separate mechanisms:
__get() for non-existing properties
__call() for calls to non-existing methods
Python has only one mechanism, because it does not distinguish between properties and methods, as far as it is concerned they are all attributes.
__getattr__() is invoked, when an attribute does not exist.
obj.non_existing() is not special "call syntax", it's an expression to which the call operator () is applied: (obj.__getattr__("non_existing"))()
Disclaimer: __getattr__() is not always called when an attribute does not exist. __getattribute__() takes the highest precedence in the lookup chain and may thus cause __getattr__() to be ignored.
Descriptors
__get__() in Python is something completely different from what has been addressed above.
The documentation describes descriptors to be "a descriptor is an object attribute with “binding behavior”". I can sort of form an intuitive understanding what "binding behavior" is supposed to mean, but only because I already understand what descriptors do.
I would choose to describe descriptors as "self-aware attributes" that can be shared across multiple classes.
Let me explain, what I mean by "self-awareness". Such attributes:
know when they are being accessed or read from
know when they are being written to
know whom they are read/written via
know when they are deleted
These attributes are independent objects: the "descriptor" objects, i.e. objects that adhere to the so called "descriptor protocol", which defines a set of methods along with their corresponding signature that such objects can implement.
An object does not own a descriptor attribute. In fact, they belong to the object's corresponding class (or an ancestor thereof). However, the same descriptor object can "belong" to multiple classes.
Note: "whom they are read via", what is the proper way to refer to obj in obj.attr? I would say: attr is accessed "via" obj.
You will find detailed documentation for all those methods here.
Coming from PHP, you should first make yourself familiar with the Python object model. It's much richer than PHP, so you should not try to map your PHP knowledge 1:1 to Python. If you want to develop PHP, use PHP. If you want to develop in Python, learn Python.
Coming back to your original question: __getattr__ is probably the function which does the same as the __get function in PHP. __get__ in Python is used to implement descriptors. Details about descriptors can also be found in the documentation I mentioned above.
Related
Following up on this documentation: https://www.php.net/manual/en/language.oop5.references.php
One of the key-points of PHP OOP that is often mentioned is that "objects are passed by references by default". This is not completely true.
In PHP, an object variable doesn't contain the object itself as value. It only contains an object identifier which allows object accessors to find the actual object.
How does this actually work? In C++ for example it seems that the arrow operator implicitly dereferences the pointer and then accesses the properties like when accessing them on the object variable itself.
Here's what I mean:
obj->prop
(*obj).prop // equivalent to line above
This seems pretty clean. The property is called as the sum of the object-variable-address and the property-offset in both cases.
But how does that work in PHP?
The documentation suggests that the pointer does not store the memory address but rather an "object-identifier". Is accessing properties in PHP a highly abstracted process or does it resolve the object-identifier for the memory address and then access it in a similar way to C++ / Java / etc.?
It's a highly abstracted process, similarity in syntax does not indicate that the code "falls through" to working like C/C++. You can dive into the code to see how it works under the covers.
Can someone please explain how overloading in PHP works? The manual doesn't do a very good job of it. I'm still thinking of overlaoding in the Java sense, but I know overloading in PHP is a completely different animal. All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this. Thanks in advance. Rylie
All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this.
The very manual page you linked to explains how the thing that PHP calls "overloading" works. You're pretty correct in that it has little to do with what the entire rest of the world calls overloading. In fact, the manual page says right at the top:
PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.
PHP has reserved a handful of special method names that you can optionally define in a class. They fall into two categories:
__get, __set, __isset and __unset are called when an instance variable (object property) is fetched, set, checked for existence, or unset respectively. All receive the name of the property as the first argument, and __set receives the new value as the second argument. These methods are only called when either the property does not exist or can not be accessed from the caller's scope (i.e. protected/private). It's worth noting that without these methods, PHP will silently create new instance variables on demand, when asked to.
__call and __callStatic are called when a method is called that, again, doesn't exist or can't be accessed from the caller's scope. The former is called for instance methods, the latter for class methods. The first argument is the name of the method called, and the second is an array of the arguments, by value (references are dereferenced).
These functions allow you to simulate adding methods to a class/instance after creation, though their use is clunky and awkward. Further, using them breaks autocomplete in IDEs.
Using anonymous functions might seem like a natural complement to this functionality, but it is currently not possible to bind an the instance ($this) to one at run time. This functionality was removed during the 5.3 beta because it couldn't be made clear and obvious. This has been corrected in PHP's current trunk, but it's unknown when the trunk will be stabilized for release.
Is there an Actionscript equivalent to PHP's __get() and __set() magic methods? I want to be able to override the behavior of getting/setting member variables.
There is no such thing, unfortunately.
All you can do is check for the existence of a specific property, by using either
myObject.hasOwnProperty (name)
on simple Objects or some variant of describeType() for Class instances, for example
describeType(myObject).accessor
to get an XMLList of all accessor methods or
describeType(myObject).variable
to get an XMLList of all variables.
describeType(), however, is quite expensive in terms of performance, so it pays to have some sort of type hash map to store the lists for each type and do lookups for types that have already been described once.
You could also use try/catch blocks around the parts where undefined properties might be accessed, but this also "eats" away a lot of performance, if many errors are thrown.
Found it.
Extending the Proxy class allows you to solve this problem.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the point of interfaces in PHP?
Why should I create Interfaces in PHP?
As I understands, interfaces are there to describe classes that implement them. The classes have to contain at least these functions. This is all fine if you're building upon someone else's work, or have to maintain a degree of compatibility. But in more simplistic cases?
I know, that for the compiled programming languages, like C++, usage of interfaces allows for an increase in compiling speed, but what about PHP? This advantage seems to disappear, since PHP is interpreted, rather than compiled.
Interfaces are a way of 'emulating' multiple inheritance. A class in PHP can extend only one parent class, but can implement any number of interfaces, thus allowing you to create objects having many different types.
Perhaps a real world example will help to illustrate this. Imagine you need to build a series of logging classes that record messages to various media such as a text file, XML or a database. Each class needs to have separate code to interact with the different types of storage of course. However if they all implement the same interface the 'public face' that they show to other code is always the same. In that way other code that uses logging objects doesn't need to know what class they are instances of or what the storage medium is. All that they need to know is that all of the logging classes, by virtue of the fact that they all implement the same interface, share a common API. This can be a very powerful way of working. You can build up a library of code that solves related problems in different ways and simply 'plug and play' these in your code.
Interfaces are used to extend/emulate core PHP behavior, like iterators, array access, etc. This is the major thing that interfaces give you... that is, you cannot do it any other way.
You can also use interfaces to enforce parameter checks:
function foo(MyInterface $obj)
{
}
While not as useful as compile time checks that you would gain in another language (e.g., C++), the run time check can still be very useful in minimizing bugs.
Finally, interfaces can simplify some logic by using the is_a function or instanceof operator. You can just check if the "abstract" object implements a certain interface, and then do something accordingly.
The usage of interfaces has nothing to do with speed and will never will.
But it has a lot to do with decoupling and abstractization.
You will use them in PHP:
To hide implementation - establish an access protocol to a class of objects an change the underlying implementation without refactoring in all the places you've used that objects
To check type - as in making sure that a parameter has a specific type $object instanceof MyInterface
To enforce parameter checking at runtime - see #konforce answer
To implement multiple behaviours into a single class (build complex types)
class Car implements EngineInterface, BodyInterface, SteeringInterface {
so that a Car object ca now start(), stop() (EngineInterface) or goRight(),goLeft() (Steering interface)
and other things I cannot think off right now
From Thinking in Java:
An interface says, “This is what all classes that implement this particular interface will look like.” Thus, any code that uses a particular interface knows what methods might be called for that interface, and that’s all. So the interface is used to establish a “protocol” between classes.
I work in php, and the concept of interfaces seems to me a little useless here. From reading, I understand that interfaces are part of "design by contract", but without at least guaranteeing a return of a type of a particular kind, there really isn't any contract. It seems it's like a contract that reads, "We agree to do the following: '' " -- there are no terms of the agreement.
If I want a guarantee that an object has a method, it doesn't seem like interfaces are particularly useful. If I try to call a method that an object doesn't have, I get a Fatal Error, so I find out pretty quickly that that class doesn't have a method with that name. If I want to be smart and check beforehand whether a class has a method, then checking the interface, and seeing whether the object implements that interface doesn't seem to save me any more time than just checking that object directly ( which I would do anyways to see if the class had that method regardless of any interfaces it did or didn't implement).
In other words, just because I have a set of methods that have particular names, that doesn't guarantee me any particular behavior. If I'm guaranteed a return of a variable of a certain type, I at least have some inkling of what the output would be, and I can write code that uses an object with that interface, because I know what I'm getting out of it. If it returns a string, I can continue coding with at least the certainty that I'm dealing with a string output afterward. So I'm guaranteed at least some behavior when a return type is specified. Is guaranteeing behavior part of what interfaces are for, or no?
The only thing I can think of is that when I'm writing code, it serves as a post-it note to myself to be sure to create certain methods when writing that class later on. It seems more like scaffolding for when I'm writing the code; I don't see much benefit from when I'm actually using it. So it's more for me to keep the standard when I'm creating classes than when I'm writing them. This benefit doesn't really seem to be captured in the concept of design by contract.
What benefit(s) do you actually get from using an interface in dynamic/loose-typed languages like PHP? Are they great, or is it something that more robust OO languages implement, so PHP implements it also?
Interfaces are used when you actually expect an object to implement a method.
For example, if I'm building a DB wrapper and it supports behaviours, which you register yourself in a bootstrap, then before running your behaviours (for example, sluggable), I will check that they implement my "DB_Wrapper_Behaviour_Interface" by using:
if(!($behaviourObject instanceof DB_Wrapper_Behaviour_Interface)) {
throw new Exception("Your behaviour doesn't implement my interface");
}
Design by contract is made more difficult without return types, but don't forget to favour 'tell' over 'ask'.
I believe an interface to be something like a responsibility. You are coding and need a collaborator. You ask it to do something because the code you are working on can't do everything. So you're asking another object to do something. An interface guarantees that the collaborator will do the job, but hides the 'how' it's done part.
Now you could argue that there's no need for the formal contract here, since the system will throw an error anyway if the collaborator can't do what you're asking it to do. But I think that misses the point in using interfaces as a responsibility.
Getting a fatal error is not always "easy". Sometimes you have to go on a specific module/action to see that something is actually missing in your class.
The interface enables you to make sure every method is implemented and to document these method (what the parameters are exactly going to be, what the return values should look like). This is useful if the parameters/values are arrays with a particular structure and you don't want to use classes instead (for the sake of simplicty).
I want to note, that PHP 5.4 will support type hinting. Right now I think there is only type hinting for function arguments, but I suppose there will be for return values, too. (At least there already is an RFC, though a very old and outdated one.)