面向对象编程:Object Oriented Programming,简称OOP,是一种程序设计思想。
需要注意的是,与之对应的是面向过程编程思想。实际上,能够使用面向对象编程思想实现的程序,也都能通过面向过程完成。只是看哪种思想更适合当前开发需求。
面向过程:根据业务逻辑从上到下写代码
面向对象:将数据与函数绑定到一起,进行封装。减少重复代码的重写过程
注意:开发中,先有类,再有对象。
类由3个部分构成
注意:类名通常采用驼峰式命名方式,尽量让字面意思体现出类的作用。
# 类的定义
class 类名称:
类的属性(成员变量)
类的行为(成员方法)
python中,可以根据已经定义的类去创建出一个个对象
创建对象的格式为:
# 创建类对象的语法
对象 = 类名称()
# 定义
class 类名:
def 方法名(self,参数): # 类中函数:称为方法
pass
# 执行
s = 类名() # 创建对象(实例) 这个过程就是实例化
s.方法名(参数) # 调用类中方法
在类当中定义方法时,会发现系统帮我们自动创建了self参数,并且在调用对象的该方法时,也无需传入self参数。
self的两个概念:
- self本身是形参
- self就是当前对象本身
class Student:
def printinfo(self):
print(lisi.name, lisi.age)
print(self.name, self.age) # 这里会高亮,对象的属性是暴露在外面的
print(lisi)
print(self)
lisi = Student() # 对象
# 对象的属性是暴露在外面的
lisi.name = '李四'
lisi.age = 38
lisi.printinfo()
"""
李四 38
李四 38
<__main__.Student object at 0x000002E5A099B208>
<__main__.Student object at 0x000002E5A099B208>
说明在类中printinfo()方法中,lisi和self是等价的
"""
在Python的类中,以两个下划线开头、两个下划线结尾的方法,如常见的 :__init__()、__str__()、__del__()等,就被称为「魔术方法」(Magic methods)。之所以会叫魔法方法原因是这些方法都是到达某个条件自动触发,无需调用,如果希望根据自己的程序定制特殊功能的类,那么就需要对这些方法进行重写。使用这些「魔法方法」,我们可以非常方便地给类添加特殊的功能。
_init_() :初始化对象
class My_Phone():
def __init__(self):
self.width = 10
self.heigth = 15
def main(self):
print(self.width)
print(self.heigth)
apple = My_Phone()
_init_() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤
_init_(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引⽤传递过去。
⼀个类可以创建多个对象,对不同的对象设置不同的初始化属性,传参即可。
class My_Phone():
def __init__(self,width,heigth):
self.width = width
self.heigth = heigth
def apple_phont(self):
print("苹果手机的宽为:",self.width)
print("苹果手机的高为:",self.heigth)
def huawei_phont(self):
print("华为手机的宽为:",self.width)
print("华为手机的高为:",self.heigth)
apple = My_Phone(10,20)
apple.apple_phont()
当使⽤print输出对象的时候,默认打印对象的内存地址。如果类定义了 str ⽅法,那么就会打印在这个⽅法中 return 的数据。
_str_():解释类的属性或作用
class Demo():
def __init__(self, width, heigth):
self.width = width
self.heigth = heigth
def __str__(self):
return f"你这个手机的宽是{self.width},高度是{self.heigth}"
a = Demo(10,20)
print(a) # 你这个手机的宽是10,高度是20
# 若没有__str__()方法,则会打印对象的内存地址:<__main__.Demo object at 0x000001E6FC7A7198>
当删除对象时,python解释器也会默认调⽤ __del__() ⽅法。在对象销毁的时候被调用,当对象不再被使用时,del()方法运行:
class Demo():
def __init__(self, width, heigth):
self.width = width
self.heigth = heigth
def __del__(self):
print("对象已经删除")
a = Demo(10,20)
# __del__方法
class Demo:
def __del__(self): # 当由该类创建的实例对象,被删除或者说在内存中被释放,将会自动触发执行。
print("被释放了!")
d = Demo()
print("*" * 20)
# del d # 相当于提前执行了del方法
print("*" * 20)
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
class Demo():
__num = 0 # 私有属性
result = 0 # 公开属性
def count(self):
self.__num += 1
self.result += 1
print(self.__num)
def getnum(self):
return self.__num
run = Demo()
run.count()
print(run.result)
# print(run.__num) # 报错,实例不能访问私有变量
__num = run.getnum()
print(__num)
class func:
def fun1(self):
print("1")
def __fun2(self):
print("2")
def fun3(self):
return (self.__fun2())
f = func()
f.fun1()
# f.__fun2()
f.fun3()
# 强行调用类的私有方法
# 对象._类名__私有属性
print(f._func__fun2) # 不建议使用
python中没有真正意义上的私有
# 实例属性
class Province:
def __init__(self, country, province):
self.country = country
self.province = province
def print_info(self):
print(self.country, self.province) # 通过self去访问 这个要方便很多
print(zs.country, zs.province) # 通过每个对象去访问
zs = Province("中国", "湖南")
zs.print_info()
ls = Province("中国", "湖北")
ls.print_info()
class Demo:
def __init__(self):
self.name = "张三"
# 实例方法
def fun1(self):
print(self.name)
a = Demo()
a.fun1()
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
根据ActiveRecord::Base的文档:==(comparison_object)Returnstrueifcomparison_objectisthesameexactobject,orcomparison_objectisofthesametypeandselfhasanIDanditisequaltocomparison_object.id.Notethatnewrecordsaredifferentfromanyotherrecordbydefinition,unlesstheotherrecordisthereceiveritself.Besides,ifyoufet