0

I have recently had to resort to using hack I didn't like, in Python2, and have been wondering - what is the reasoning - why not every object can be monkey patched, as in below example (crude, does not check for errors, but it's only for demo's sake):

import requests

def get_page():
    req = requests.get("https://stackoverflow.com")
    if req.status_code == 200:
        yield req

def prepare_some_content_in_file(file_):
    with open(file_, 'w') as _file:
        _file.write("a texty text")

def patch_file_type():
    """ WILL FAIL ! """

    file_ = "/tmp/some_so_random_name"
    prepare_some_content_in_file(file_)
    with open(file_, 'r') as _file:
        setattr(_file, "text", _file.read())
        yield _file

def patch_func_type():
    """ GO AHEAD """

    file_ = "/tmp/some_so_random_name"
    prepare_some_content_in_file(file_)
    pseudo_file = lambda: None
    with open(file_, 'r') as _file:
        setattr(pseudo_file, "text", _file.read())
        yield pseudo_file

print(get_page())
try:
    for i in patch_file_type():
        print(type(i), i, i.text)
except AttributeError as error:
    print(error)
try:
    for i in patch_func_type():
        print(type(i), i, i.text)
except AttributeError as error:
    print(error)

This concerns Python2 only, in Python3 it works:

Py2 output:

<generator object get_page at 0x7f8afa7143c0>
'file' object has no attribute 'text'
(<type 'function'>, <function <lambda> at 0x7f8afa456668>, u'a texty text')

Py3 output:

<generator object get_page at 0x7f5c37842570>
<class '_io.TextIOWrapper'> <_io.TextIOWrapper name='/tmp/some_so_random_name' mode='r' encoding='UTF-8'> a texty text
<class 'function'> <function patch_func_type.<locals>.<lambda> at 0x7f5c35a02048> a texty text

Reason for this to exist is obviously to have alternative cached file, on which I could operate same way, as on requests object, ie. call text attribute, etc.

EDIT: In response to comments:

dir(_file)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']


dir(pseudo_file) # lambda acutally
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

None of them have property __slots__ which is discussed for class in examples. I'll look if anything there can be treated in similar way.

JustMe
  • 670
  • 4
  • 16
  • @juanpa.arrivillaga: I don't think that's a good dupe. This question is about "why can't I do this", not "can I do this" or "what can I do instead". – user2357112 supports Monica Mar 30 '17 at 19:05
  • This question does not answer why, what is the reasoning behind - maybe someone can point to some PEP or there is other logical explanation for that. – JustMe Mar 30 '17 at 19:06
  • Ok, perhaps it's a bad target, but there are *tons* of similar questions. It is certainly a duplicate. – juanpa.arrivillaga Mar 30 '17 at 19:06
  • Maybe [this](http://stackoverflow.com/questions/1285269/why-cant-you-add-attributes-to-object-in-python) is a better dupe target. – juanpa.arrivillaga Mar 30 '17 at 19:08
  • Well, if really *tons* then probably You could pinpoint to exactly such that explains why? I'd be grateful. – JustMe Mar 30 '17 at 19:08
  • Or maybe [this](http://stackoverflow.com/questions/623520/why-cant-i-directly-add-attributes-to-any-python-object?rq=1) – juanpa.arrivillaga Mar 30 '17 at 19:10
  • Yeah, those are better. – user2357112 supports Monica Mar 30 '17 at 19:10
  • The accepted answer to [this one](http://stackoverflow.com/questions/1529002/cant-set-attributes-of-object-class) probably has the most detail. – juanpa.arrivillaga Mar 30 '17 at 19:11
  • Those discuss `class`, which have `__slots__` but maybe this is a good lead, I'll dig into this. – JustMe Mar 30 '17 at 19:12
  • ok, questions linked indicate that `type(file)` is lacking of implementation of \__dict__ attribute, and thus `setattr` won't work. Actually I did not found reason behind this, but since SO members think it's duplicated and the answer is there, I'll leave this as such. – JustMe Mar 30 '17 at 19:21

0 Answers0