[英]Check if string contains any string in list with forbiddenfruit
Suppose I want to check if a string contains any string in a list. 假设我要检查字符串是否在列表中包含任何字符串。 One way to do this is
一种方法是
word = 'hello world'
any(substring in word for substring in ['hello','apple'])
although this seems a bit verbose to me. 尽管这对我来说似乎有些冗长。 Ideally I want
理想情况下,我要
word.ContainsAny('hello','apple')
I've read that an extension method like this for built-in objects can be done with the forbiddenfruit package, but I can't work out how. 我已经读过,可以使用forbiddenfruit包来完成针对内置对象的扩展方法,但是我无法解决。 Could someone show me, or maybe suggest more concise methods?
有人可以告诉我,还是建议更简洁的方法?
Edit: I'm aware I could write a function like this: 编辑:我知道我可以编写这样的函数:
ContainsAny(word,['hello','apple'])
but the extension method looks neater to me. 但是扩展方法对我来说显得更整洁。
Well, you can subclass str
: 好吧,您可以将
str
子类化:
class MyStr(str):
def ContainsAny(self, *args):
return any(substring in word for substring in args)
word = MyStr('hello world')
word.ContainsAny('hello', 'apple') # True
But it's questionable why you'd create a subclass for aesthetic access to a single method. 但是令人怀疑的是, 为什么要创建一个子类以美观地访问单个方法。
Seems to be straightforward with forbiddenfruit: 禁果似乎很简单:
>>> from forbiddenfruit import curse, reverse
>>> def contains_any(self, *args):
... return any(substring in self for substring in args)
...
>>> curse(str, "contains_any", contains_any)
>>> word = "hello world"
>>> word.contains_any("hello", "apple")
True
I really have to agree that this is a terrible idea though. 我确实必须同意这是一个糟糕的主意。 Quoting from the forbiddenfruit readme:
引用禁果自述文件:
may lead you to hell if used on production code.
如果用于生产代码,可能会导致您下地狱。
>>> import string
>>> class MyString(str):
... def disemvowel(self):
... return MyString(string.translate(self, None, "aeiou"))
...
>>> s = MyString("this is only a test")
>>> s.disemvowel()
'ths s nly tst'
From comment: 来自评论:
https://stackoverflow.com/a/15975791/10552105 https://stackoverflow.com/a/15975791/10552105
import functools
import ctypes
import __builtin__
import operator
class PyObject(ctypes.Structure):
pass
Py_ssize_t = hasattr(ctypes.pythonapi, 'Py_InitModule4_64') and ctypes.c_int64 or ctypes.c_int
PyObject._fields_ = [
('ob_refcnt', Py_ssize_t),
('ob_type', ctypes.POINTER(PyObject)),
]
class SlotsPointer(PyObject):
_fields_ = [('dict', ctypes.POINTER(PyObject))]
def proxy_builtin(klass):
name = klass.__name__
slots = getattr(klass, '__dict__', name)
pointer = SlotsPointer.from_address(id(slots))
namespace = {}
ctypes.pythonapi.PyDict_SetItem(
ctypes.py_object(namespace),
ctypes.py_object(name),
pointer.dict,
)
return namespace[name]
def die(message, cls=Exception):
"""
Raise an exception, allows you to use logical shortcut operators to test for object existence succinctly.
User.by_name('username') or die('Failed to find user')
"""
raise cls(message)
def unguido(self, key):
"""
Attempt to find methods which should really exist on the object instance.
"""
return functools.partial((getattr(__builtin__, key, None) if hasattr(__builtin__, key) else getattr(operator, key, None)) or die(key, KeyError), self)
class mapper(object):
def __init__(self, iterator, key):
self.iterator = iterator
self.key = key
self.fn = lambda o: getattr(o, key)
def __getattribute__(self, key):
if key in ('iterator', 'fn', 'key'): return object.__getattribute__(self, key)
return mapper(self, key)
def __call__(self, *args, **kwargs):
self.fn = lambda o: (getattr(o, self.key, None) or unguido(o, self.key))(*args, **kwargs)
return self
def __iter__(self):
for value in self.iterator:
yield self.fn(value)
class foreach(object):
"""
Creates an output iterator which will apply any functions called on it to every element
in the input iterator. A kind of chainable version of filter().
E.g:
foreach([1, 2, 3]).__add__(2).__str__().replace('3', 'a').upper()
is equivalent to:
(str(o + 2).replace('3', 'a').upper() for o in iterator)
Obviously this is not 'Pythonic'.
"""
def __init__(self, iterator):
self.iterator = iterator
def __getattribute__(self, key):
if key in ('iterator',): return object.__getattribute__(self, key)
return mapper(self.iterator, key)
def __iter__(self):
for value in self.iterator:
yield value
proxy_builtin(list)['foreach'] = property(foreach)
import string
print string.join([1, 2, 3].foreach.add(2).str().add(' cookies').upper(), ', ')
>>> 3 COOKIES, 4 COOKIES, 5 COOKIES
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.