It there an equivalent to PHP's extract in Python? [duplicate] - php

This question already has answers here:
Python equivalent of PHP's compact() and extract()
(6 answers)
Closed 7 years ago.
Looking for the python equivalent of this.
http://php.net/extract

Maybe you would be better off explaining what you are trying to do. Any solution to the direct question would be rather unpythonic as there is almost certainly a better way to do what you want.
EDIT (per your comments):
And indeed, there is a better way.
What you are trying to do is known as unpacking argument lists, and can be done like this:
self.__api_call__('POST', '/api/foobar/', **mydict)
A working example:
>>> def a_plus_b(a,b):
... return a+b
...
>>> mydict = {'a':3,'b':4}
>>> a_plus_b(**mydict)
7
And it also works with kwargs, as you might expect:
>>> def a_plus_b(**kwargs):
... return kwargs['a'] + kwargs['b']
...
>>> a_plus_b(**mydict)
7

no. why do you need it?
do the following (see comment)
def __api_call__(self, method, resource, **kwargs):
print(kwargs)
def do_call(my_dict):
self.__api_call__('POST', '/api/foobar/', **your_dict) # double asterisk!

One generally uses locals() to achieve this result, but the exact functionality is up to you.
>>> print apple
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'apple' is not defined
>>> print banana
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'banana' is not defined
>>> variables = {"apple" : "a rigid, juicy fruit", "banana" : "a soft, fleshy fruit"}
>>> for variable,value in variables.iteritems():
... locals()[variable] = value
...
>>> print apple
a rigid, juicy fruit
>>> print banana
a soft, fleshy fruit
EDIT
Thanks to everyone who has diligently commented on the badness of this approach. I wholeheartedly agree that THIS IS A BAD APPROACH, and it deserves to be mentioned in the actual response for anyone who stumbles across this page. (Never underestimate that; I saw this technique in a code snippet somewhere. I can see why in that particular case it was harmless, but I know I can't go around encouraging bad methodology just because there are situations in which it won't break.)

IMO it is at least a nice theoretical question: how such construction can be implemented and how does it look like once it is applied?
For instance, as a function it can be implemented as
import inspect
def extract_attribute(obj, names):
if type(names) == str:
names = [names]
# Get previous frame from the inspect stack.
frame = inspect.stack()[1][0]
try:
frame_locals = frame.f_locals
attributes = inspect.getmembers(
obj, lambda attr: not inspect.ismethod(attr))
for name, attribute in attributes:
if name.startswith('__') or name.endswith('__'):
continue
if name in names:
frame_locals[name] = attribute
finally:
del frame
del frame_locals
and used as
class A(object):
foo = 'bar'
a = A()
extract_attribute(a, 'foo')
assert locals()['foo'] == 'bar'
assert foo == 'bar
Note: await pylint will complain on the last line. One can find *extract_attribute* function working with object in somewhat similar way to import functionality for modules. Applying it as additional layer of scope coupling (mixed with present import) will increase complexity of the code almost without exceptions.
PS
Obvious enough manipulating built-in is a sign of doing something python was not designed to do. But self-flattering mantras like not-practical and "non-pythonic" are not really proper arguments to me. In general it is always much more "practical" to make an experiment and to see if:
1. Construction will enrich the expressiveness of the language (e.g. making it more readable and natural-like), give new functionality, etc.
2. Construction is too ugly and dangerous to be used, too flexible and unsafe, performance trade-offs are unacceptable, etc.
Illustration and test by explicit example is a preferred alternative. Looking at code everyone is free to make his own opinion without sharing the "professional guts" or copy-pasting religious dogmas. Please don't.

Related

PHP: Select enum case from string value of case name

I'm looking at enum in PHP 8.1. I have a string variable gathered from a database record, and I want to select the correct enum value case based on that string. For example:
enum Test: string {
case FOO = 'baz';
case BAR = 'buz';
}
I can select the first of those using the string value of the case:
$x = 'baz';
$y = Test::from($x);
// $y is now `Test::FOO`.
But what about the other way around? What if $x = "FOO"? How do I select the enum case from "FOO"?
Hard-coded, it would be Test::FOO, but I don't know the syntax for using a variable. I've tried a few things like Test::{$x} but the enum syntax doesn't seem to like variables very much.
The standard example all the tutorials give seems a perfect use case for this usage, but none of them mention it.
enum Suit: string {
case Clubs = '♣';
case Diamonds = '♦';
case Hearts = '♥';
case Spades = '♠';
}
I can totally imagine needing to get ♣ from "Clubs". I can't imagine ever needing the reverse.
To me, storing the name of the constant and not the value defeats the purpose of a backed enum. But, reading through many of the discussions on enums, many people were against backed enums and/or stringified enums in general, so I won't argue the point except to say that I would consider it the same as storing Clubs for a class constant such as:
class Suit
{
const Clubs = '♣';
const Diamonds = '♦';
const Hearts = '♥';
const Spades = '♠';
}
To your question, yes you can get the enum back by using the constant function (as noted in this thread):
enum Suit: string {
case Clubs = '♣';
case Diamonds = '♦';
case Hearts = '♥';
case Spades = '♠';
}
$cardString = 'Clubs';
$cardEnumFQString = Suit::class . '::' . $cardString;
$cardEnum = constant($cardEnumFQString);
echo $cardEnum->value;
Demo here: https://3v4l.org/WTrIv#v8.1.10
Personally, when I use backed enums it is for database, URL transport or similar, and I use the value. If I want to expose anything user-facing I more often than not just add a custom attribute and I have a common utility function that parses that.
EDIT Here's some helper code that shows a trait I use to reflect on enum attributes: https://3v4l.org/QKBvU#v8.1.10. It might seem like overkill for some people, but for some objects I like to keep their meta information attached to the object instead of a separate render file.
EDIT: Enums vs Class Constants
This is not a definitive answer to the question in any way, I want to make that clear. There is definitely a lot more that I'm not covering and I'd encourage a read-through on the original discussion as well as the follow-up discussion and the over-arching ADTs RFC. There's a lot in those discussions, pros, cons, WTFs, alternatives, "I don't get it", etc.
One of the major differences between an enum and a class constant is that an enum is a first-class object in PHP and as such it can have methods, whereas a class constant is limited to scalars, scalar expressions and arrays (ignoring recent post-enum changes). This means you can pass an object that holds a specific value around, and have that object include methods. The PHP documentation has a great example for the color method on Suit.
You could define your constants in one file and include a utility class with methods like getColor(string $colorName) however there's no way to limit the choices that get passed to it, nor can you guard against someone using a literal instead of your constant.
Can you do that with pure classes? Absolutely, and many of us used libraries such as https://github.com/myclabs/php-enum or https://github.com/spatie/enum to do that. This just unifies it at the language level.
I definitely agree that it can be a grey area. I came from a .Net background originally so I've had enums for a very long time, and even wrote a "why enums vs static class members" over a decade ago, so for me I've had a long time to play with them, and was very excited when they came to PHP. The best I can tell you is that you might just have to play with them to see if they fit. I'm very certain that some long-time PHP people won't use enums ever because they've solved this problem in the past in other ways, and I think that's okay, too.

Structuring Decorators in PHP

I'm sort of a novice developer trying to expand my toolbox and learn some more tricks. I recently came across a pattern in Python called "decoration" and I was wondering if/how I could implement this in PHP as I have an existing PHP code base.
Here is a short example of what I mean:
import time
def log_calls(func):
def wrapper(*args, **kwargs):
now = time.time()
print("Calling {0} with {1} and {2}".format(
func.__name__,
args,
kwargs
))
return_value = func(*args, **kwargs)
print("Executed {0} in {1}ms".format(
func.__name__,
time.time() - now
))
return return_value
return wrapper
#log_calls
def test1(a,b,c):
print("\ttest1 called")
#log_calls
def test2(a,b):
print("\ttest2 called")
#log_calls
def test3(a,b):
print("\ttest3 called")
time.sleep(1)
test1(1,2,3)
test2(4,b=5)
test3(6,7)
It doesn't necessarily have to be that syntactically pretty; I understand that all languages have their nuances and I know PHP does not support that syntax. But I still want to be able to achieve the same effect while rewriting as little code as possible.
Basically no, it's not supported in PHP in any way at all. As far as I know, it's not even on the roadmap for future PHP versions.
Of interest, and slightly relevant: The closest I could think of in PHP-land to what you're after is if you use phpUnit to test your code. phpUnit implements something along these lines for its own use, using references in docblock type comments above a method. eg:
/**
* #dataProvider myProviderFunc
*/
public function myTestFunc($argsFromProvider) {
....
}
public function myProviderFunc() {
return array(....);
}
Thus, when phpUnit wants to call myTestFunc(), it first calls myProviderFunc(), and passes the output of that function into myTestFunc().
This strikes me as being close to, but not quite the same as the decorator syntax you're describing. However, it's not standard PHP syntax; phpUnit implements all of this stuff itself. It reads the source code and does a load of pre-processing on as it parses the comment blocks before running the tests, so it's not exactly efficient. Suitable for a unit testing tool, but not for a production system.
But no, the short answer to your question is that what you want can't be done in PHP. Sorry.
PHP has no syntactic support for the decorator pattern, but nothing really hinders you from implementing it yourself.
You can look into the following discussions, which might be relevant to your question:
how to implement a decorator in PHP?
Trying to implement (understand) the Decorator pattern in php
Here is another resource, with UML diagrams and code samples in multiple languages, including PHP.
Decorator Design Pattern

Where can I get a list of reflection modifier values?

This function returned 524320 for one my classes. If I run it through getModifierNames, it tells me:
>> Reflection::getModifierNames(524320)
array (
0 => 'abstract',
)
Which is correct, but 524320 isn't a power of 2, so it must have some other flags? Actually, if we look at it's binary representation, 10100111 it looks like it has 5 flags set. So what are the other 4, and where can I find a list of all of them?
Edit: Now I'm confused... the representation is actually 10000000000000100000, according to this. Which makes sense, because that corresponds to "explicit abstract class". Oh... I bet this was an overflow issue now that I'm thinking about...must investigate a bit more.
See the ZEND_ACC_* constants in http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_compile.h#144
Mind that some of these are internal and are not exported in anyway to userspace. The ones exported to userspace ones can be found in http://php.net/manual/en/class.reflectionmethod.php and other classes.

PHP code to convert PHP to JS [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need some PHP code to convert some PHP into JS.
functionality - I'm using common PHP functions from php.js
syntax - ???
The issue is converting the syntax. I don't need full PHP syntax, mind you; no need for supporting class definitions/declarations. Here's a small checklist of what needs conversion:
"." should be "+" (string concat)
"->" should be "." (object operator)
"::" should be "." (class operator - not really required)
Please note that the resulting code is pretty much independent of the PHP environment, so no "what if it uses a PHP class?".
I'm not asking for full code, just a tip on the right direction to this kind of conversion; I was thinking about employing a state machine/engine.
If you're curious as to why I'm pushing code to the user side: I need a dynamic way to change visibility of certain elements given certain conditions. My plan is to do this without having to execute this code server side and having unnecessary ajax calls.
Edit: Look people. I know not using AJAX sounds ludicrous to you but the world doesn't work on hype and nice-sounding design conditions (=ajax). I simply can't afford each single user polling my server 5 to 10 times per second just for my server to return a "yes" or "no" answer. Keep in mind that switching is asynchronous, and I can't buffer the AJAX calls.
Edit 2: I am sure what I'm doing is the best way in my situation. There is no "possibly better" way, so quit posting non-constructive comments. I can't get into any more detail than I have so already. The conversion from PHP code to JS is simply a matter of shortening user input; we only need one expression, then convert it to whichever language is necessary (in this particular case, from PHP to JS). The conditions on how this works will not change regardless if I describe the system down to the API specs, and inundating the topic with useless (for you) prototype docs will not help at all.
Also, for those thinking this idea came after waking up form some dream; know this has been reviewed between technical development and QA, so please do not deviate into inexistent design issues.
Edit 3: Examples (original PHP code and expected output):
(original) -- (converted)
5=="test" -- 5=="test"
'$'.(func(12)*10) -- '$'+(func(12)*10)
Fields::count()==5 -- Fields.count()==5
$this->id==5 -- this.id==5
About the last example, don't worry about context/scope, it is correct. Also note that the expressions may look weird; this is because they are expression; a single line of code that must return a value, which explains the absence of an EOL (;) and the multiple use of returning a boolean value. (exotic stuff like backtick operator execution, PHP tags, echo, die, list, etc.. left out on purpose)
Okay, let me take a stab at this one...
Screw regexes. I love them, but there's a better way, and it's built in. Check out token_get_all(). It will parse PHP source as a string and return a list of the very same tokens that PHP itself uses (including the beloved T_PAAMAYIM_NEKUDOTAYIM). You can then completely reconstruct the source of the script, one token at a time, translating it into Javascript syntax along the way.
[charles#teh ~]$ php --interactive
Interactive shell
php > print_r(token_get_all('<?php class Foo { public function bar() { echo "Yikes!"; } } $f = new Foo(); $f->bar(); ?>'));
Array
(
[0] => Array
(
[0] => 368
[1] => <?php
[2] => 1
)
[1] => Array
(
[0] => 353
[1] => class
[2] => 1
)
[2] => Array
(
[0] => 371
[1] =>
[2] => 1
)
[3] => Array
(
[0] => 307
[1] => Foo
[2] => 1
)
...
While this may be a bit overkill, it also uses the same parsing rules PHP uses, and should therefore be less of a long-term pain than regular expressions. It also gives you the flexibility to detect features that can't be translated (i.e. things that php-js doesn't support) and reject the translation and/or work around the problem.
Also, you still haven't told us what you're doing and why you're doing it. There are still probably more accurate, useful answers available. Help us help you by giving us more information.
You believe polling to be unrealistic due to an expected stupidly high number of requests per second. Why are you expecting that number? What does your application do that would cause such conditions?
Why do you want to translate PHP code rather than writing specific Javascript? You're just manipulating page contents a bit, why do you need PHP code to make that decision?
Language translation is probably the least simple solution to this problem, and is therefore an amazingly awful idea. It couldn't have been arrived at as the first option. What are your other options, and why have they been ruled out?
Have you tried Harmony Framework?
Here's the quick and dirty solution I came up with, written in under 20 minutes (probably lots of bugs), but it looks like it works.
function convertPhpToJs($php){
$php=str_split($php,1); $js='';
$str=''; // state; either empty or a quote character
$strs=array('\'','`','"'); // string quotes; single double and backtick
$nums=array('0','1','2','3','4','5','6','7','8','9'); // numerals
$wsps=array(chr(9),chr(10),chr(13),chr(32)); // remove whitespace from code
foreach($php as $n=>$c){
$p=isset($php[$n-1])?$php[$n-1]:'';
$f=isset($php[$n+1])?$php[$n+1]:'';
if($str!='' && $str!=$c){ $js.=$c; continue; } // in a string
if($str=='' && in_array($c,$strs)){ $str=$c; $js.=$c; continue; } // starting a string
if($str!='' && $str==$c){ $str=''; $js.=$c; continue; } // ending a string
// else, it is inside code
if($c=='$')continue; // filter out perl-style variable names
if($c==':' && $f==':'){ $js.='.'; continue; } // replace 1st of :: to .
if($p==':' && $c==':')continue; // filter out 2nd char of ::
if($c=='-' && $f=='>'){ $js.='.'; continue; } // replace 1st of -> to .
if($p=='-' && $c=='>')continue; // filter out 2nd char of ->
if($c=='.' && (!in_array($p,$nums) || !in_array($f,$nums))){ $js.='+'; continue; } // replace string concat op . to +
if(in_array($c,$wsps))continue; // filter out whitespace
$js.=$c;
}
return $js;
}
The following:
$window->alert("$".Math::round(450/10));
Converted to:
window.alert("$"+Math.round(450/10));
Edit: Can't believe all the fuss this question caused compared to the time taken.
Feel free to criticize at will. I don't actually like it much personally.
I wrote a tool called php2js that can automatically convert PHP code to javascript. It is not perfect, but supports the most common PHP functionality including classes, inheritance, arrays, etc, etc. It also includes and knows about php.js, so code written with php's standard library functions may "just work".
Maybe you will find it useful.
Im created tool PHP-to-JavaScript for converting PHP code to JavaScript. Its support:
Namespaces,use
Class, abstract class extends and interfaces
constants and define
Exceptions and catch
list()
magic methods __get __set and __call
and more

Why are configuration arrays acceptable parameters in PHP and Javascript?

In most other Object Oriented languages. it would be sacrilege to have each function receive a single associative array of Objects rather than enumerating each in the method signature. Why though, is it acceptable and commonly used in most popular frameworks for both of these languages to do this?
Is there some justification beyond wishing to have concise method signatures?
I do see a benefit in this -- that the API could remain unchanged as new, optional parameters are added. But Javascript and PHP already allow for optional parameters in their method signatures. If anything, it seems like Java or another OO language would benefit from this more... and yet I rarely see this pattern there.
What gives?
In my opinion, a lot of these functions are climbing in the number of arguments they accept, over 10 is not uncommon. Even if you do optional parameters, you still have to send them in order.
Consider a function like:
function myFunc(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13){
//...
}
Say you want to use arguments 3 and 11 only. Here is your code:
myFunc(null, null, null, 'hello', null, null, null, null, null, null, null, 'world');
Wouldn't you rather just:
myFunc({
a3 : 'hello',
a11 : 'world'
});
?
There are a couple of reasons for this.
The first is that not all argument lists have a natural order. If there is a use-case to only supply the 1st and 6th argument, now you have to fill in four default placeholders. Jage illustrates this well.
The second is that it's very hard to remember the order the arguments must occur in. If you take a series of numbers as your arguments, it's unlikely to know which number means what. Take imagecopyresampled($dest, $src, 0, 10, 0, 20, 100, 50, 30, 80) as an example. In this case, the configuration array acts like Python's named arguments.
The major reason is that those particular languages simply do not support having multiple calling conventions for the same function name. I.E. you can't do the following:
public function someFunc(SomeClass $some);
public function someFunc(AnotherClass $another);
public function someFunc(SomeClass $some, AnotherClass $another);
So you must find another way to create simpler ways to pass your variables around, in PHP we end up with someFunc(array('some'=>$some, 'another'=>$another)) because it is the only convenient way. In JavaScript we end up using objects, which isn't as bad: someFunc({some: something, another: anotherthing})
Ruby follows this methodology as well, and has even devised a more succinct syntax meant specifically for using hashes as initializers, as of Ruby 1.9:
# old syntax
myFunc(:user => 'john', :password => 'password');
# new syntax
myFunc(user: 'john', password: 'password');
The problem being addressed is that, within these languages, you cannot overload functions based on argument type. This results in complex classes with a single constructor that can have a huge and unwieldy argument list. Using hash-like objects to supply parameters allows for a sort of pseudo-overloading by parameter name rather than by type.
My only real problem with this practice is it becomes difficult to document your arguments:
PHPDoc for variable-length arrays of arguments
One of the most important reason why you don't see this in other OO languages is that you are probably referring to compiled languages like C++ or Java.
The compiler is responsible to determine, at compilation time not during execution, which method you want to call and this is normally done based on the signature, so basically it has to be done this way. This is also how method overload is done in these languages.
First of all such technique is very simple for the coders.
They do not need to remember order of all of the parameters of the all functions in your application. The code becomes more readable and more robust.
Any future development, improvements or refactoring will be no so hard to provide. The code becomes more maintainable.
But there is some pitfalls. For example, not every IDE will give you a simple code completing with such functions and their parameters.
In my opinion there 2 reasons why this has evolved:
Array's are very easy to create and manipulate, even with mixed types.
PHP/JS programmers have often a non academic background and are less indoctrinated from languanges like Java and C++.

Categories