我正在尝试运行此代码,但似乎exec()
没有在函数内执行字符串:
def abc(xyz):
for i in fn_lst:
s = 'temp=' + i + '(xyz)'
exec(s)
print (temp)
abc('avdfbafadnf')
我收到的错误:
NameError Traceback (most recent call last)
<ipython-input-23-099995c31c78> in <module>()
----> 1 abc('avdfbafadnf')
<ipython-input-21-80dc547cb34f> in abc(xyz)
4 s = 'temp=' + i + '(word)'
5 exec(s)
----> 6 print (temp)
NameError: name 'temp' is not defined
fn_lst
是一个函数名列表,即:['has_at', 'has_num' ...]
如果可能的话,请让我知道exec()
的替代方案。
答案 0 :(得分:6)
我没有足够的声望点来添加评论,但我想提一下 DrM 之前的回答不起作用(在函数内):
def test():
exec( 'a = 3', globals(), locals() )
print(a)
test()
此代码在 Python 3 中出现错误:
NameError: name 'a' is not defined
我使用其他论坛中建议的 compile
函数尝试了一些方法,但它们仍然对我不起作用(至少在我看到提到的选项时)。
根据我的研究,这是我见过的最接近的代码:
def test():
lcls = locals()
exec( 'a = 3', globals(), lcls )
a = lcls["a"]
print(f'a is {a}')
test()
它成功打印:
a is 3
我认为这是一个很重要的话题。有时,当您使用符号代数库(如 Sympy)时,通过 exec
函数定义变量对于科学计算非常方便。
我希望有人知道这个问题的好答案。
答案 1 :(得分:3)
要通过传递给exec()的字符串设置变量,在调用之外可用,请使用exec(),如下所示:
//sample xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layoutDirection="rtl"
tools:context=".SampleActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.booking.rtlviewpager.RtlViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
// fragment_main xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="44dp"
android:textDirection="anyRtl"
android:textColor="#ffffff"
android:textSize="60dp" />
</LinearLayout>
// SampleActivity class :
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public class SampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.sample);
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
//TextViewPagerAdapter adapter = new TextViewPagerAdapter(7);
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), new String[]{"الاحد ","الاثنين ","الثلاثاء ","الاربعاء"});
viewPager.setAdapter(adapter);
tabs.setupWithViewPager(viewPager);
}
public class MyPagerAdapter extends FragmentPagerAdapter{
private String [] strings;
public MyPagerAdapter(FragmentManager fm , String []stringstodisplay) {
super(fm);
this.strings = stringstodisplay;
}
@Override
public Fragment getItem(int pos){
return FragmentViewPager.newInstance(strings[pos]);
}
@Override
public int getCount() {
return strings.length;
}
}
static class TextViewPagerAdapter extends PagerAdapter {
private int pages;
TextViewPagerAdapter(int pages) {
this.pages = pages;
}
@Override
public int getCount() {
return pages;
}
@Override
public Object instantiateItem(final ViewGroup container, int position) {
// Text Page
final String item = "" + position;
final TextView text = new TextView(container.getContext());
text.setGravity(Gravity.CENTER);
text.setBackgroundColor(Color.WHITE);
text.setTextColor(Color.BLACK);
text.setTextSize(30);
text.setText(item);
container.addView(text, MATCH_PARENT, MATCH_PARENT);
text.setTag(item);
return item;
}
@Override
public CharSequence getPageTitle(int position) {
return String.valueOf(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return object.equals(view.getTag());
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(container.findViewWithTag(object));
}
// End -------------- ;
}
}
// FragmentViewPager class :
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class FragmentViewPager extends android.support.v4.app.Fragment {
// ArabicUtilities.reshapeSentence(
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
TextView tv = (TextView) v.findViewById(R.id.title);
tv.setText(getArguments().getString("text"));
//tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
//ImageView imageView = (ImageView) v.findViewById(R.id.image);
//imageView.setBackgroundResource(getArguments().getInt("img"));
return v;
}
public static FragmentViewPager newInstance(String text) {
FragmentViewPager f = new FragmentViewPager();
Bundle b = new Bundle();
b.putString("text", text);
// b.putInt("img", image);
f.setArguments(b);
return f;
}
}
例如,
exec( a_string, locals(), globals() )
将打印以下结果:
exec( 'a = 3', locals(), globals() )
print( a )
注意:在这个例子中,单独使用locals()就足够了,即省略globals()。两者都包括在这里,以说明更一般的情况。 locals()和/或globals()的使用是更大主题的一部分,称为“Scope”。您可以在Python Textbook - Scope
了解详情答案 2 :(得分:3)
在这个问题上花了这么多时间做hit和trial之后,我可以说像这样使用exec在函数内部没有任何问题,否则它会抛出错误。 我已经对函数和变量进行了测试。
def main():
x = "def y():\n\treturn('This will work')"
#pass only globals() not locals()
exec(x,globals())
print(y())
main()
def test():
#pass only globals() not locals()
exec( 'a = 3', globals())
print(a)
test()
这是在 W3School's online interpreter 上工作的屏幕截图(您可以自己复制/粘贴并在此处测试)
答案 3 :(得分:0)
不要将exec
与函数名一起使用,只需将函数对象保留在列表中:
fn_lst = [has_at, has_num, ...]
直接执行调用:
def abc(xyz):
for i in fn_lst:
temp= i(xyz)
print(temp)