I keep getting 500 error on post which is why this response has taken a lot of time…
@facelessuser - You’re right - As it is loaded into memory, yes my implementation would override the default and other modules would use the new implementation, however as the effects of an additional function would be negligible it wouldn’t bother or affect the object in any way which is noticeable… as I understand it, many languages strive to be as optimized as possible. This means, and I know this is true for Java, that when you extend an object, create a new one, etc… the data is only loaded once and only the data which changes is actually saved… Any time there is a duplicate of something, that duplicate is simply stored as the originals memory address until it changes.
It would be wrong of me to assume this is true for Python without doing additional research which I am happy to do. If it is the case then the difference between my additions would be incredibly small and no object actually doing anything with the function until it is used and each object would only save their string and not the functions as a copy… If I were designing a language, I’d do something similar because I prefer to be efficient and not requiring classes to be completely copied to each and every instance would mean memory use would free-fall… I’d like to think the Python creators did this, but again - I’ll do the research.
I tried numerous ways to override str ( and it may actually be _ _ builtins _ _ and not _ _ builtin _ _ ) and ran into wall after wall… I believe I tried the import method you’re suggesting as well with no luck, I also tried an @update method, etc… Just in case I didn’t, I will try it again.
I just tried it, and as I thought it doesn’t override str for my package, or any other…
Using a simply MyString class, from Package import MyString as str — ‘Test’.reverse( ) — str as no attribute reverse…
builtins doesn’t exist, builtin doesn’t exist… etc…
@ThomSmith - It isn’t dangerous if you are familiar enough with the language and the rules defined by the language… in addition to how it operates… If a future version includes reverse( ) my reverse( ) would still work unless they fundamentally change how [ : ] operates which is unlikely unless a MAJOR version change comes, and still it is very unlikely because it’d break many many scripts… When replacing or changing such a huge feature, popular languages give businesses a lot of time and a head start to update - but again… it’s incredibly unlikely this will happen because businesses that rely on Python may instead of updating their version of Python remain back, and if there is a security flaw this is a huge problem… another reason why languages tend to remain the same…
Additionally, if a future version creates version - as I said it wouldn’t affect mine - but I could then remove mine from my string library, or add it differently - for example similar to how I add AccessorFuncs - on initialization of the package itself, I could check to see if str.reverse exists and if it does then I don’t create it…
If someone else updates String, it would still work regardless of who replaces it first… If my package runs first and replaces str with mine - then another package loads and replaces str ( which is now mine ) then they simply extend mine which extends str… It works in reverse order too… That’s the point of inheritance…
If someone else adds a reverse function, the rules would be the same and they should both be backwards compatible but only one would be active, whichever replaces str last… reverse is a simple example of a function though and while there are many ways to do it - some slower / more costly to run than others - the end result would be the same so it’d still work.
I do understand all of the arguments against, but I have a lot of experience with this in dozens of other languages. I know how to make these backwards compatible if I replace an existing function ( which is NOT what I am doing here ), or if I create new functions then I’d follow the naming conventions of the language so everything operates naturally, and if the language adds the function then all I have to do is disable mine but I would design them to be as identical to the way the language would add them as possible. Heck, I typically even submit my implementations for approval to give a greater chance of them being accepted. I also teach how to properly reroute, update, add, etc… without interfering in the language because that’s something else I teach - how to properly match the standards of languages a company uses to keep the code as professional as possible as that’s something incredibly important when businesses hire someone to develop for them… Otherwise code would take way too long to maintain and the business would lose money in addition to looking incredibly unprofessional ( if the company ever sells itself and the buyer ends up getting a rats-nest then it’s typically less expensive to either outsource to rewrite from scratch or in-source to rewrite - reformatting code takes a long time ).
The problem with not being able to update built in objects means instead of simply being able to run ‘Testing’.reverse( ), you have to run MyStringClass( ‘Testing’ ).reverse( ) which takes much longer to write - it also means that existing code would need ALL of it’s strings to be altered in order to use the new object. It also makes the size of the file much larger and it goes against one of my rules - don’t repeat code which isn’t, or shouldn’t be necessary… This is to increase efficiency…
I understand why it may be frowned upon because it means anyone could simply start adding hundreds of functions which aren’t necessary or end up doing the same thing other functions already do - but if you do the proper amount of research and know how the developers add new features, how they’re most likely going to implement something, or to use it as a tool to get more interested in developing by building confidence because the code is easier to understand right away, the proper standards are used when adding the new functions, etc… then there’s no problem.
Here’s basically what happens…
# My File - without comments, etc...
class MyString( str ):
def reverse( self ):
return self[ : : - 1 ]
__builtin__.str = MyString
now str is MyString which extends str by adding reverse to it… 1 function… Now, if someone else wants to update str, since str returns builtin.str they will extend MyString… so they do:
# them
TheirString( str ):
# Removes a chunk from a string starting at _index and removing _len chars...
def snip( self, _index = 0, _len = 1 ):
return self[ 0 : _index - 1 ] + self[ _index + _len - 1 : ]
__builtin__.str = TheirString
Granted, the second example isn’t necessary when snipping chars from the left or right of the string because strip r / l already does that. So not enough research has gone in to see a user-friendly / readable function exists for these cases… Now to snip some from the center, that’s different… it could use another function name, but the function above for snip strange to follow… it doesn’t just snip… it can snip chars, duplicate with offset while still snipping at least 1 char, etc… it isn’t predictable enough and therefore not enough thought has gone into it for it to be named snip… Never trust user input, and this function doesn’t do what it advertises so it is a terrible example of what should be added and a perfect example of what not to do…
If Python devs added a snip from char for len chars function they’d ensure it’d do exactly that with no unexpected behavior while allowing - offsets for the starting character, or -len to snip from the starting char in reverse ( and they’d likely NOT remove the 10th char, for instance if using start at 10 and remove -1 so the 9th char would be removed… and for 1 the 10th char would be removed )…
However, because MyString is str, as stated, TheirString extending str actually extends MyString. so it doesn’t matter which order they are called…
Granted if they add reverse and use a for loop to copy each string to a new string in reverse order - that’s definitely bad because there’s already a built-in method to do it more elegantly but not in a user-readable ( or beginner readable ) way…