我通常会尝试确保我的对象实例符合Liskov替换原则,但我一直想知道人们是否认为LSP也应该适用于构造函数?
我已经尝试使用谷歌搜索,但无论如何我都无法找到任何强烈的意见.
我应该注意到我的大部分编码都是在Ruby中,但我有时会发现我的子类构造函数与父类略有不同.它们使用相同的基本参数集,通常是额外的参数.有时这也会发生在其他类方法中.
在我的脑后,这总是感觉像LSP违规,但我想看看是否有其他人也有这种感觉.
我已经阅读了Python中的什么类方法?但那篇文章中的例子很复杂.我正在寻找Python中类方法的特定用例的清晰,简单,简单的例子.
您能说出一个小的,具体的示例用例,其中Python类方法将是该工作的正确工具吗?
我有一个类:
class MyClass:
Foo = 1
Bar = 2
Run Code Online (Sandbox Code Playgroud)
每当MyClass.Foo
或被MyClass.Bar
调用时,我都需要在返回值之前调用自定义方法.在Python中有可能吗?我知道如果我创建一个类的实例,我可以定义自己的__getattr__
方法.但我的scnenario涉及使用此类,而不创建任何实例.
另外,我需要__str__
在调用时str(MyClass.Foo)
调用自定义方法.Python提供这样的选项吗?
Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
Run Code Online (Sandbox Code Playgroud)
只是基于方法的名称,我希望class_eval允许你向Foo和instance_eval添加一个类方法,以允许你向Foo添加一个实例方法.但他们似乎反其道而行之.
在上面的例子中,如果你在Foo类上调用class_bar,你会得到一个未定义的方法错误,如果你在Foo.new返回的实例上调用instance_bar,你也会得到一个未定义的方法错误.这两个错误似乎都与对class_eval和instance_eval应该做什么的直观理解相矛盾.
这些方法之间有什么区别?
class_eval的文档:
mod.class_eval(string [,filename [,lineno]])=> obj
在mod的上下文中计算字符串或块.这可以用于向类添加方法.
obj.instance_eval {| | block} => obj
在接收器(obj)的上下文中计算包含Ruby源代码或给定块的字符串.为了设置上下文,在代码执行时将变量self设置为obj,使代码可以访问obj的实例变量.
我是ActiveRecord新查询界面的新手,所以我还在搞清楚.
我希望有人可以解释scope
在ActiveRecord模型中使用a和使用类方法之间的区别(即self.some_method
)
从我可以收集的内容来看,范围总是希望返回一个关系,而一个类方法不一定必须.这是真的?
例如,我认为做以下事情是有意义的:
class Person
scope :grouped_counts, group(:name).count
end
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我收到此错误:
ArgumentError: Unknown key(s): communicating, failed, matched, unmatched
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activesupport-3.0.5/lib/active_support/core_ext/hash/keys.rb:43:in `assert_valid_keys'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/relation/spawn_methods.rb:110:in `apply_finder_options'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/named_scope.rb:110:in `block in scope'
from (irb):48
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
r
Run Code Online (Sandbox Code Playgroud)
但它确实可以作为一种类方法
def self.grouped_counts
group(:name).count
end
Run Code Online (Sandbox Code Playgroud)
我很想知道人们关于何时使用范围以及何时使用类方法的想法.我是否正确假设范围必须始终返回关系,但是类方法可以返回它想要的任何内容?
我真的不需要这样做,但只是想知道,有没有办法将装饰器绑定到类中的所有函数,而不是明确地为每个函数声明它.
我认为它然后变成了一种方面,而不是装饰者,它确实感觉有点奇怪,但是想到时间或认证这样的东西它会非常整洁.
防爆.
如果我有这样的事情:
class C(object):
@classmethod
def f(cls, x):
return x + x
Run Code Online (Sandbox Code Playgroud)
这将有效:
c = C()
c.f(2)
4
Run Code Online (Sandbox Code Playgroud)
但这是不好的形式?我应该只打电话
C.f()
Run Code Online (Sandbox Code Playgroud)
要么
c.__class__.f()
Run Code Online (Sandbox Code Playgroud)
显然,这只有在f不与self/cls相互作用的情况下才有意义.
?
我使用过几种不同的语言,如Java,C#和Objective-C.
在大多数语言中,不需要对象实例的方法称为静态方法.然而,当谈到Objective-C时,有些人在你称之为静态方法时会变得防守,并且他们希望你将它们称为类方法.
为什么他们称为类方法而不是静态方法?静态方法和类方法有什么区别?
在Ruby中是否有任何方法可以知道它存在多少个实例并且可以列出它们?
这是一个示例类:
class Project
attr_accessor :name, :tasks
def initialize(options)
@name = options[:name]
@tasks = options[:tasks]
end
def self.all
# return listing of project objects
end
def self.count
# return a count of existing projects
end
end
Run Code Online (Sandbox Code Playgroud)
现在我创建这个类的项目对象:
options1 = {
name: 'Building house',
priority: 2,
tasks: []
}
options2 = {
name: 'Getting a loan from the Bank',
priority: 3,
tasks: []
}
@project1 = Project.new(options1)
@project2 = Project.new(options2)
Run Code Online (Sandbox Code Playgroud)
我想是有类方法一样Project.all
,并Project.count
返回一个列表和当前项目的计数.
我该怎么做呢?
如何测试Rails命名范围?您是否测试从作用域返回的结果,或者您的查询是否正确配置?
如果我有一个User
类如下的.admins
方法:
class User < ActiveRecord::Base
def self.admins
where(admin: true)
end
end
Run Code Online (Sandbox Code Playgroud)
我可能会确保我得到我期望的结果:
describe '.admins' do
let(:admin) { create(:user, admin: true) }
let(:non_admin) { create(:user, admin: false) }
let(:admins) { User.admins }
it 'returns admin users' do
expect(admins).to include(admin)
expect(admins).to_not include(non_admin)
end
end
Run Code Online (Sandbox Code Playgroud)
我知道这会导致对数据库的命中,但如果我想测试范围的行为,我真的没有看到任何其他选择.
但是,最近我看到通过确认它们的配置正确而不是返回的结果集来确定范围.对于此示例,类似于:
describe '.admins' do
let(:query) { User.admins }
let(:filter) { query.where_values_hash.symbolize_keys }
let(:admin_filter) { { admin: true } }
it 'filters for admin users' do
expect(filter).to eq(admin_filter) # …
Run Code Online (Sandbox Code Playgroud) class-method ×10
python ×4
class ×2
oop ×2
ruby ×2
activerecord ×1
constructor ×1
decorator ×1
getattr ×1
liskov-substitution-principle ×1
named-scope ×1
objective-c ×1
rspec ×1
scopes ×1
terminology ×1