试图找到一种方法来清理我的一些代码.
所以,我的Python代码中有这样的东西:
company = None
country = None
person = Person.find(id=12345)
if person is not None: # found
company = Company.find(person.companyId)
if company is not None:
country = Country.find(company.countryId)
return (person, company, country)
Run Code Online (Sandbox Code Playgroud)
在阅读了关于Haskell的monad(特别是Maybe)的教程后,我想知道是否可以用另一种方式编写它.
Kat*_*iel 39
company = country = None
try:
person = Person.find(id=12345)
company = Company.find(person.companyId)
country = Country.find(company.countryId)
except AttributeError:
pass # `person` or `company` might be None
Run Code Online (Sandbox Code Playgroud)
jfs*_*jfs 26
利用短路行为,默认情况下自定义对象为true,None为false:
person = Person.find(id=12345)
company = person and person.company
country = company and company.country
Run Code Online (Sandbox Code Playgroud)
dfl*_*str 16
Python对monad没有特别好的语法.话虽如此,如果你想限制自己使用像Maybemonad 这样的东西(意思是你只能使用Maybe;你将无法制作处理任何monad的泛型函数),你可以使用以下做法:
class Maybe():
def andThen(self, action): # equivalent to Haskell's >>=
if self.__class__ == _Maybe__Nothing:
return Nothing
elif self.__class__ == Just:
return action(self.value)
def followedBy(self, action): # equivalent to Haskell's >>
return self.andThen(lambda _: action)
class _Maybe__Nothing(Maybe):
def __repr__(self):
return "Nothing"
Nothing = _Maybe__Nothing()
class Just(Maybe):
def __init__(self, v):
self.value = v
def __repr__(self):
return "Just(%r)" % self.value
Run Code Online (Sandbox Code Playgroud)
然后,使当前返回的所有方法None返回Just(value)或Nothing替代.这允许您编写此代码:
Person.find(id=12345).andThen(lambda person: Company.find(person.companyId)).andThen(lambda company: Country.find(company.countryId))
Run Code Online (Sandbox Code Playgroud)
您当然可以调整lambdas以将中间结果存储在变量中; 这取决于你如何正确地做到这一点.
我认为这是一个完美的情况getattr(object, name[, default]):
person = Person.find(id=12345)
company = getattr(person, 'company', None)
country = getattr(company, 'country', None)
Run Code Online (Sandbox Code Playgroud)
您检查了PyMonad吗?
https://pypi.python.org/pypi/PyMonad/
它不仅包括Maybe monad,还包括列表monad,Functor和Applicative functor类。Monoids等。
在您的情况下,它将类似于:
country = Person.find(id=12345) >> (lambda person:
Company.find(person.companyId) >> (lambda company:
Country.find(company.countryId))
Run Code Online (Sandbox Code Playgroud)
比EAFP更容易理解和清洁。