我目前正在尝试优化我的Python程序并开始使用Cython以减少函数调用开销,并且可能稍后包括优化的C库函数.
所以我遇到了第一个问题:
我在我的代码中使用组合来创建一个更大的类.到目前为止,我已经将我的一个Python类转换为Cython(这很难).这是代码:
import numpy as np
cimport numpy as np
ctypedef np.float64_t dtype_t
ctypedef np.complex128_t cplxtype_t
ctypedef Py_ssize_t index_t
cdef class bendingForcesClass(object):
cdef dtype_t bendingRigidity
cdef np.ndarray matrixPrefactor
cdef np.ndarray bendingForces
def __init__(self, dtype_t bendingRigidity, np.ndarray[dtype_t, ndim=2] waveNumbersNorm):
self.bendingRigidity = bendingRigidity
self.matrixPrefactor = -self.bendingRigidity * waveNumbersNorm ** 2
cpdef np.ndarray calculate(self, np.ndarray membraneHeight):
cdef np.ndarray bendingForces
bendingForces = self.matrixPrefactor * membraneHeight
return bendingForces
Run Code Online (Sandbox Code Playgroud)
从我编写的Python/Cython类中,我调用了类方法calculate,因此在我的编写类中,我有以下(简化)代码:
from bendingForcesClass import bendingForcesClass
cdef class membraneClass(object):
def __init__(self, systemSideLength, lowerCutoffLength, bendingRigidity):
self.bendingForces …Run Code Online (Sandbox Code Playgroud) 我正在玩可组合的失败并设法用签名编写一个函数
getPerson :: IO (Maybe Person)
Run Code Online (Sandbox Code Playgroud)
一个人在哪里:
data Person = Person String Int deriving Show
Run Code Online (Sandbox Code Playgroud)
它的工作原理我用以下的方式编写了它:
import Control.Applicative
getPerson = do
name <- getLine -- step 1
age <- getInt -- step 2
return $ Just Person <*> Just name <*> age
Run Code Online (Sandbox Code Playgroud)
哪里
getInt :: IO (Maybe Int)
getInt = do
n <- fmap reads getLine :: IO [(Int,String)]
case n of
((x,""):[]) -> return (Just x)
_ -> return Nothing
Run Code Online (Sandbox Code Playgroud)
我编写此函数的目的是创建可组合的可能失败.虽然我对除了Maybe和IO之外的monad的经验很少,但是如果我有一个更复杂的数据类型以及更多的字段,那么链接计算并不复杂.
我的问题是,如果没有写符号,我将如何重写?由于我无法将值绑定到名称或年龄等名称,因此我不确定从哪里开始.
提问的原因只是为了提高我对(>> =)和(<*>)的理解,并构成失败和成功(不要用难以辨认的单行代码来捣乱我的代码).
编辑:我想我应该澄清一下,"我应该怎么重写getPerson而不用do-notation",我不关心getInt函数的一半.
Scala有两种用于表达对象组成的工具:原始的自我类型概念和众所周知的琐碎组合.我很好奇我应该使用哪种情况.
它们的适用性存在明显差异.自我类型要求您使用特征.对象组合允许您使用var声明在运行时更改扩展.
留下技术细节我可以找到两个指标来帮助分析用例.如果某些物体用作复杂结构的组合器,例如树或只有几个相似的类型部件(1车到4轮关系),它应该使用组合物.有一个极端相反的用例.让我们假设一个特征变得太大而无法清楚地观察它并且它被分裂了.在这种情况下你应该使用自我类型是很自然的.
那条规则不是绝对的.你可以做额外的工作来在这些技术之间转换代码.例如,您可以使用Product4替换自动打字的4个车轮组合.您可以使用Cake[T <: MyType] {part : MyType}而不是Cake { this : MyType => }蛋糕模式依赖项.但这两种情况看起来都是违反直觉的,给你额外的工作.
虽然有很多边界用例.一对一的关系很难决定.是否有任何简单的规则来决定哪种技术更可取?
self-type使你的类抽象化,组合使你的代码变得冗长.自我类型给你混合命名空间的问题,并且还免费为你提供额外的打字(你不仅仅是两种元素的混合物,而是汽油机油鸡尾酒,称为汽油炸弹).
我如何在它们之间做出选择?有什么提示?
更新:
我们来讨论以下示例:
适配器模式.选择打字和组合方法有什么好处?
如何实现组合模式?我有一个Container具有属性对象的类Contained.我想通过简单地调用来重定向/允许访问所有Contained类的方法.我是否以正确的方式做正确的事情?Containermy_container.some_contained_method()
我使用类似的东西:
class Container:
def __init__(self):
self.contained = Contained()
def __getattr__(self, item):
if item in self.__dict__: # some overridden
return self.__dict__[item]
else:
return self.contained.__getattr__(item) # redirection
Run Code Online (Sandbox Code Playgroud)
背景:
我正在尝试构建一个类(Indicator),它增加了现有类(pandas.DataFrame)的功能.Indicator将拥有所有的方法DataFrame.我可以使用继承,但我遵循"赞成组合而不是继承 "的建议(参见例如:python:inheriting或composition中的答案).不继承的一个原因是因为基类不可序列化,我需要序列化.
我发现了这个,但我不确定它是否符合我的需要.
我通常使用组件组合来重用逻辑React方式.例如,这是一个关于如何将交互逻辑添加到组件的简化版本.在这种情况下,我会CanvasElement选择:
CanvasElement.js
import React, { Component } from 'react'
import Selectable from './Selectable'
import './CanvasElement.css'
export default class CanvasElement extends Component {
constructor(props) {
super(props)
this.state = {
selected: false
}
this.interactionElRef = React.createRef()
}
onSelected = (selected) => {
this.setState({ selected})
}
render() {
return (
<Selectable
iElRef={this.interactionElRef}
onSelected={this.onSelected}>
<div ref={this.interactionElRef} className={'canvas-element ' + (this.state.selected ? 'selected' : '')}>
Select me
</div>
</Selectable>
)
}
}
Run Code Online (Sandbox Code Playgroud)
Selectable.js
import { Component } from 'react'
import PropTypes from 'prop-types' …Run Code Online (Sandbox Code Playgroud) javascript composition higher-order-functions reactjs higher-order-components
当我Composing Types从Haskell Book 学习章节时,我被赋予编写以下类型的Functor和Applicative实例的任务。
newtype Compose f g a = Compose { getCompose :: f (g a) }
Run Code Online (Sandbox Code Playgroud)
我写了以下定义
fmap f (Compose fga) = Compose $ (fmap . fmap) f fga
Run Code Online (Sandbox Code Playgroud)
(Compose f) <*> (Compose a) = Compose $ (<*>) <$> f <*> a
Run Code Online (Sandbox Code Playgroud)
我了解到,组成两个Functor或Applicatives分别会给Functor和Applicative。
作者还解释说,不可能以相同的方式组成两个Monad。因此,我们使用Monad变形金刚。我只是不想阅读Monad Transformers,除非我清楚为什么Monad不作曲。
到目前为止,我尝试编写如下bind函数:
(>>=) :: Compose f g a -> (a -> Compose f g b) -> Compose f g b
(Compose fga) >>= h = (fmap.fmap) h …Run Code Online (Sandbox Code Playgroud) 我理解F#中函数组合的基础知识,例如,这里描述的.
也许我错过了一些东西.在>>与<<运营商似乎已经与各功能只需要一个参数的假设定义:
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@214-13>
> (<<);;
val it : (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b) = <fun:it@215-14>
Run Code Online (Sandbox Code Playgroud)
但是,我想做的事情如下:
let add a b = a + b
let double c = 2*c
let addAndDouble = add >> double // bad!
Run Code Online (Sandbox Code Playgroud)
但即使add输出是输入所需的类型double,也会被拒绝.
我知道我可以用一个元组参数重写add:
let add (a,b) = a + b
Run Code Online (Sandbox Code Playgroud)
或者我可以为第一个函数的每个可能的参数编写一个新的运算符: …
我需要知道是否可以通过扩展它来为某个POJO JPA实体(使用hibernate提供程序)添加一些属性和行为,然后使entityManager返回扩展对象而不仅仅是pojo实体,如下例所示:
POJO JPA实体类
@Entity
@Table("test")
public class Test implements Serializable {
}
Run Code Online (Sandbox Code Playgroud)
扩展类
public class ExtendedTest extends Test {
...
}
Run Code Online (Sandbox Code Playgroud)
获取扩展类的对象
List<ExtendedTest> extendedList = entityManager.createNamedQuery("ExtendedTest.findByFoo").setParameter("foo", "bar").getResultList();
Run Code Online (Sandbox Code Playgroud)
我正在评估的另一种可能方式是使用复合实体扩展功能并委派所有setter和getter,但这可能意味着对大型表的大量工作:
public class ExtendedTest2 {
private Test test;
public ExtendedTest2(Test test) {
this.test = test;
}
public getFoo() {
return test.getFoo();
}
public getBar() {
return test.getBar();
}
...
}
Run Code Online (Sandbox Code Playgroud)
任何建议将非常感谢.
我在Stackoverflow上看到很多帖子解释了关系之间的区别:关联,聚合,组合和继承,以及示例.但是,我更加特别地混淆了每种方法的优缺点,并且当一种方法对于手头的任务最有效时.这是我无法真正找到一个好答案的东西.
与论坛的指导方针保持一致,我不是要问为什么人们可能会个人更喜欢使用继承而不是构图.我对每种方法中的任何客观利益/弱点都特别感兴趣,这听起来有点强烈.即,一种方法创建比另一种更可读的代码,或者它具有更好的运行时效率等.
理想情况下,如果有人可以给我一些真实世界的例子,这些方法可能已成功或失败,为什么,这对于发展我和我希望的其他知识非常有用.
为了确保一个可靠的基础,我已经在Python 2中包含了每个关系的例子.如果我对这些关系的理解实际上不正确,那么这应该可以避免混淆.
协会
B类与A类具有周关联关系,因为它在addAllNums方法中使用A中的特定属性.但是,这就是关系的程度.
class A(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def addNums():
self.b + self.c
class B(object):
def __init__(self, d, e):
self.d = d
self.e = e
def addAllNums(self, Ab, Ac):
x = self.d + self.e + Ab + Ac
return x
ting = A("yo", 2, 6)
ling = B(5, 9)
print ling.addAllNums(ting.b, ting.c)
Run Code Online (Sandbox Code Playgroud)
聚合
B类与A类形成聚合关系,因为它在初始化时引用独立的A对象作为其属性之一.虽然B对象依赖于A,但是在B被破坏的情况下,A将继续存在,因为它独立于B.
class A(object):
def __init__(self, a, b, c): …Run Code Online (Sandbox Code Playgroud) 如果我有一个Role R定义为:
role R { method answer { 42 } }
Run Code Online (Sandbox Code Playgroud)
这两行之间有什么区别(如果有的话):
my $a = 'question' does R;
my $b = 'question' but R;
Run Code Online (Sandbox Code Playgroud)
它们看起来非常相似:
say $a.answer; # OUTPUT: «42»
say $b.answer; # OUTPUT: «42»
say $a.WHAT; # OUTPUT: «(Str+{R})»
say $b.WHAT; # OUTPUT: «(Str+{R})»
Run Code Online (Sandbox Code Playgroud)
这是一个有不止一种方法可以做到这一点的情况吗,这两者的意思是一样的?还是我遗漏了细微的差别?
注:
据我所知,does是既操作者和性状,因此当用于编译时混入(例如,可使用class C does R {}),而but仅仅是用于运行时混入。我也明白but可以与对象(例如,my $c = 'question' but False)does一起使用,而只能与Role. 我不是在问这些差异中的任何一个。我唯一的问题是在运行时使用Role …
composition ×10
python ×3
haskell ×2
inheritance ×2
monads ×2
aggregation ×1
associations ×1
class ×1
cython ×1
f# ×1
hibernate ×1
java ×1
javascript ×1
jpa ×1
methods ×1
mixins ×1
oop ×1
pandas ×1
raku ×1
rakudo ×1
reactjs ×1
scala ×1
self-type ×1