__包含__和Python3.8枚举

时间:2020-05-14 11:54:47

标签: python enums

设置:Python 3.8.2;一些带有重载Future<User> createUser (String url,{Map body}) async{ String userId; return http.post(url, body:body).then((http.Response response){ if (response.statusCode < 200 || response.statusCode > 400 || json == null) { throw new Exception("Error while fetching data"); } print(json.decode(response.body)); var extractdata = json.decode(response.body); userId = extractdata["uid"]; print(userId); return User.fromJson(json.decode(response.body)); }); } class Register extends StatefulWidget { @override _RegisterState createState() => _RegisterState(); } class _RegisterState extends State<Register> implements RegisterPageContract{ BuildContext _ctx; final _formKey = new GlobalKey<FormState>(); final scaffoldKey = new GlobalKey<ScaffoldState>(); bool loading = false; RegisterPagePresenter _presenter; User newUser; static final create_url = "http://www.hiddenmasterminds.com/web/index.php?r=featured/createinitialstudent"; TextEditingController firstNameInputController; TextEditingController lastNameInputController; TextEditingController emailInputController; TextEditingController pwdInputController; TextEditingController confirmPwdInputController; TextEditingController mobileNoInputController; TextEditingController referCodeInputController; @override initState() { firstNameInputController = new TextEditingController(); lastNameInputController = new TextEditingController(); mobileNoInputController = new TextEditingController(); emailInputController = new TextEditingController(); pwdInputController = new TextEditingController(); confirmPwdInputController = new TextEditingController(); referCodeInputController = new TextEditingController(); super.initState(); _presenter = RegisterPagePresenter(this); } void _submit(){ final form = _formKey.currentState; if(form.validate()){ loading = true; form.save(); _presenter.doRegister(firstNameInputController.text.toString(), firstNameInputController.text.toString(), emailInputController.text.toString(), mobileNoInputController.text.toString(), pwdInputController.text.toString(), "comp", "sppu", "pict", "abc", "123", "cdv" ); } } String error = ''; bool _showPassword = false; bool _showConfirmPassword = false; bool checkBoxValue = true; @override void dispose() { pwdInputController.dispose(); super.dispose(); } String emailValidator(String value) { Pattern pattern = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; RegExp regex = new RegExp(pattern); if (!regex.hasMatch(value)) { return 'Email Format Is Invalid'; } else { return null; } } String pwdValidator(String value) { if (value.length < 8) { return 'Password Must Be Longer Than 8 Characters'; } else { return null; } } String confirmPwdValidator(String val) { if(val.isEmpty) return 'Empty'; if(val != pwdInputController.text) return "Password Doesn't Match"; return null; } @override Widget build(BuildContext context) { _ctx = context; final bgColor = const Color(0xFF4b0081); return loading ? Loading() : Scaffold( resizeToAvoidBottomInset: false, backgroundColor: bgColor, body:SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( padding: const EdgeInsets.only(top:30.0, right: 30, left: 30, bottom: 100), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ SizedBox(height: 25.0,), TextFormField( validator: (val) { if (val.length < 3) { return "Enter a Valid First Name"; } return null; }, decoration: InputDecoration( labelText: "First and Last Name", hintText: "John Joe", labelStyle: TextStyle(color: Colors.white), prefixIcon: Icon( Icons.perm_identity, color: Colors.blue[400], ) ), controller: firstNameInputController, style: TextStyle(color: Colors.white, fontSize: 17.0), ), TextFormField( validator: (val) => val.length != 10 ? "Enter a 10 Digit Mobile Number" : null, decoration: InputDecoration( prefixIcon: Icon( Icons.phone_android, color: Colors.blue[400], ), labelText: "10 Digit Mobile Number(for OTP)", hintText: "94XXXXXX12", labelStyle: TextStyle(color: Colors.white) ), controller: mobileNoInputController, keyboardType: TextInputType.number, style: TextStyle(color: Colors.white, fontSize: 17.0), ), TextFormField( validator: (val) => emailValidator(val), controller: emailInputController, keyboardType: TextInputType.emailAddress, decoration: InputDecoration( prefixIcon: Icon( Icons.mail, color: Colors.blue[400], ), labelText: "Email ID", hintText: "john.doe@gmail.com", labelStyle: TextStyle(color: Colors.white) ), style: TextStyle(color: Colors.white, fontSize: 17.0), ), TextFormField( validator: (val) => pwdValidator(val), controller: pwdInputController, decoration: InputDecoration( prefixIcon: Icon( Icons.lock, color: Colors.blue[400], ), labelText: "Passoword", hintText: "********", labelStyle: TextStyle(color: Colors.white), suffixIcon: GestureDetector( onTap: (){ setState(() { _showPassword = !_showPassword; }); }, child: Icon( _showPassword ? Icons.visibility : Icons.visibility_off, color: Colors.blue[400], ) ), ), style: TextStyle(color: Colors.white, fontSize: 17.0), obscureText: !_showPassword, ), TextFormField( validator: (val) => confirmPwdValidator(val), controller: confirmPwdInputController, decoration: InputDecoration( prefixIcon: Icon( Icons.lock, color: Colors.blue[400], ), suffixIcon: GestureDetector( onTap: (){ setState(() { _showConfirmPassword = !_showConfirmPassword; }); }, child: Icon( _showConfirmPassword ? Icons.visibility : Icons.visibility_off, color: Colors.blue[400], ) ), labelText: "Confirm Passoword", hintText: "********", labelStyle: TextStyle(color: Colors.white) ), style: TextStyle(color: Colors.white, fontSize: 17.0), obscureText: !_showConfirmPassword, ), TextFormField( controller: referCodeInputController, decoration: InputDecoration( prefixIcon: Icon( Icons.insert_emoticon, color: Colors.blue[400], ), labelText: "Refer Code(If Any)", labelStyle: TextStyle(color: Colors.white) ), style: TextStyle(color: Colors.white, fontSize: 17.0), ), SizedBox(height: 15.0,), Row( children: <Widget>[ Checkbox( value: checkBoxValue, onChanged: (bool value){ setState(() { checkBoxValue = value; }); }, ), Text('By Clicking This You Agree All The Terms and Conditions.', style: TextStyle( color: Colors.white, fontSize: 10 ), ) ], ), RaisedButton( color: Colors.white, child: Text( 'Register', style: TextStyle(color: bgColor), ), onPressed: () async { newUser = new User(firstName:firstNameInputController.text.toString(), lastName: lastNameInputController.text.toString(),emailId:emailInputController.text.toString(), mobile: mobileNoInputController.text.toString(),password: pwdInputController.text.toString(), department: "comp",univ_name: "abc",college_name: "hello", university_year: "234",build_no: "234",android_no: "asd"); User p = await createUser(create_url,body:newUser.toMap()); // _submit(); }, splashColor: Colors.grey, ), SizedBox(height: 12.0,), Text( error, style: TextStyle( color: Colors.red, fontSize: 14.0 ), ), FlatButton( color: bgColor, child: Text( 'Already Have An Account? Login Here!', style: TextStyle(color: Colors.white), ), onPressed: () async { Navigator.pushNamed(_ctx, './SignIn'); }, ), ], ), ), ), ], ), ), ); } 函数的枚举类。

^((.*[0-9]+)[a-zA-Z]+.*)|((.*[a-zA-Z]+)[0-9]+.*)$

测试1 :使用枚举本身的值。

__contains__()

工作正常(此处结果= from enum import Enum class Something(Enum): A = 1 def __contains__(self, Other): return Other in self.__class__.__members__.keys() )。

测试2 :使用非枚举值。

  print("A:", Something.A in Something)

失败,即

A: True

问题

如何实现 print("1:", 1 in Something) 功能,其中左操作数可以是任何值?也就是说,应该可以编写类似

的内容
  TypeError: unsupported operand type(s) for 'in': 'int' and 'EnumMeta'

而不必检查in的类型。

1 个答案:

答案 0 :(得分:3)

定义Something.__contains__可使您编写类似1 in Something.A的内容。对于您想要的内容,您需要子类EnumMeta并将其结果用于定义Something

从某种意义上说,Enum.__new__ 已经已经完成了我们想要的检查;将值传递给类型要么返回适当的实例,要么引发ValueError

>>> Something.A
<Something.A: 1>
>>> Something(Something.A)
<Something.A: 1>
>>> Something(1)
<Something.A: 1>
>>> Something(3)
ValueError: 3 is not a valid Something

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
[...]

因此,我们新的元类的__contains__方法只需尝试从给定类型中检索给定值,如果成功则返回True,如果引发异常则返回False。 / p>

from enum import EnumMeta, Enum

class MyMeta(EnumMeta):

    def __contains__(self, other):
        try:
            self(other)
        except ValueError:
            return False
        else:
            return True


class Something(Enum, metaclass=MyMeta):
    A = 1


assert Something.A in Something
assert 1 in Something
assert 2 not in Something

如果您想让1 in Something返回False,只需抓住TypeError提出的super().__contains__

class MyMeta(EnumMeta):
    def __contains__(self, other):
        try:
            return super().__contains__(other)
        except TypeError:
            return False