Why is ACCESS EXCLUSIVE LOCK necessary in PostgreSQL?
If you have a look at the documentation, you see the list of operations that obtains this type of lock:


  Acquired by the DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL,
  and REFRESH MATERIALIZED VIEW (without CONCURRENTLY) commands. Many
  forms of ALTER TABLE also acquire a lock at this level.


All those are physically (re)moving rows, so reading would be at least very unpredictable during these.

Talking about transactions, when you start reading from a table and another process decides slightly later to drop it, the latter must wait until the read finishes - the earlier will still get the data requested, and when that transaction commits, the second one takes the lock and drops the table.  The other way around, the read will just fail after the wait from the dropping transaction to commit, as there is nothing to read from anymore.

If PostgreSQL allowed to read from a table being dropped, that would mean two things.  One is, if I am not mistaken, that there existed a READ UNCOMMITTED isolation level.  While you can choose that, it is in fact READ COMMITTED, meaning that no transaction is able to see intermediary states of other transactions.  The other one is, as you already guessed, that possibly only a portion of the desired data is returned.  This would lead to unpredictable behaviour, and that's the last thing you want from a database system.

Moreover, CLUSTER and VACUUM FULL are moving data between two files - how could one decide in which file to chase the rows?

All in all, in some cases reading data is not so urgent.  Or in the case of DROP TABLE and TRUNCATE it is not so urgent anymore.