3 When Objects are Alike
来源:互联网 发布:淘宝美国代购推荐 编辑:程序博客网 时间:2024/06/06 03:29
1、class variables && instance variables
class Contact: all_contacts = [] str = "" def __init__(self,name,email): self.name = name self.email = email #self.all_contacts.append(self) Contact.all_contacts.append(self)
class variables,即类变量,它是类定义的一部分,all_contacts即是,如同C++里的static,是属于类的,所有实例共享这个类变量;instance variables,实例变量,它是属于某个实例的,类中用self.引用的即是。需要注意的时,类变量在引用时一定是用class.classVariable这种方式,而不能用self.classVariable或instance.classVariable,有时这两种方式虽然也是可以的,但更多时间会出错,这涉及到Python变量可变与不可变:
python中,一切都是对象,故不存在传值还是传址,因为全都是传址。而这些变量中,又分为:
- 可变对象:可变是指它的内容是可变的,有列表、字典等
- 不可变对象:元组、字符串、数值型等
a = 1 #申请一段内存,值为1,把a指向这段内存b = a #把b指向a的内存b = 2 #因为数值型不可变,所以又申请一段内存,值为2,把b指向这段内存print a is b #False,地址不相同
a = [1,2]b = a #b指向a指向的内存b[0] = 3print a is b #True,因为list的内容是可变的,故还是指向同一段内存b = [] #类型不可变,故申请一段内存,把b指向这段新的内存,而a不变print a is b #False
2、继承
class Supplier(Contact): def test(self): print "YES"
在类后面的括号里写明父类即表示继承,如果没有写父类,python默认会继承object这个类。同样,如果没有重载__init__这个函数,则默认调用父类的__init__。
3、继承内置对象
现在我们有一个需求:需要在all_contents里找到所有name==v的数据:
class Contact: all_contacts = [] str = "" def __init__(self,name,email): self.name = name self.email = email self.str = name Contact.str = email Contact.all_contacts.append(self) def search(self,name): match_contacts = [] for contact in Contact.all_contacts: if contact.name == name: match_contacts.append(contact) return match_contacts c = Contact("moment","moment@gmail.com")b = Contact("mmm","F")可以在Contact里加一个search函数,然后通过instance.func的方式调用(不能用class.func调用,会报错,不知道为什么,能用这种方式访问变量,却不能访问函数)。但这个方法属于all_contacts更好,因为它是个list,且不属于任何实例。我们可以这样:
class ContactList(list): def search(self,name): m = [] for contact in self: if name is contact.name: m.append(contact) return m class Contact: all_contacts = ContactList() def __init__(self,name,email): self.name = name self.email = email self.str = name Contact.str = email Contact.all_contacts.append(self)
我们先构造了一个继承list的类,然后定义了search方法,并将all_contacts变为这个类的实例。
当然,如果有需要,object,list,set,dict,file,str等都可以被继承。
4、override
class Supplier(Contact): def __init__(self,name,email,phone): super(Supplier, self).__init__(name,email) self.phone = phone在重载时,我们可以用super(子类,self)来引用父类的函数。
注意:super函数只能应用于新类,新类是指那些什么都不用继承,那就继承object的类。在上面的例子中,Contact什么都没继承,而其子类Supplier中引用了super,所以会报错:TypeError: must be type, not classobj。只要将Contact继承object即可。
5、多继承
假设Supplier有地址需要存储,我们建立AdderssHolder类:
class AddressHolder: def __init__(self, city, street): self.city = city self.street = street而Supplier可以这样继承:
class Supplier(Contact, AddressHolder): def __init__(self,name,email,phone, city, street): Contact.__init__(self, name, email) AddressHolder.__init__(self, city, street) self.phone = phone
在初始化时,我们指定了父类,这种方法有潜在的危险:假如Contact和AddressHolder有同一个父类A,那么父类A的__init__可能会被多次调用,如
class BaseClass(object): num_base_calls = 0 def call_me(self): print("Calling method on Base Class") self.num_base_calls += 1 class LeftSubclass(BaseClass): num_left_calls = 0 def call_me(self): print "left: before super" super(LeftSubclass,self).call_me() print("Calling method on Left Subclass") self.num_left_calls += 1 class RightSubclass(BaseClass): num_right_calls = 0 def call_me(self): print "right: before super" super(RightSubclass,self).call_me() print("Calling method on Right Subclass") self.num_right_calls += 1 class Subclass(LeftSubclass, RightSubclass): num_sub_calls = 0 def call_me(self): super(Subclass,self).call_me() print("Calling method on Subclass") self.num_sub_calls += 1s = Subclass()s.call_me()print(s.num_sub_calls, s.num_left_calls, s.num_right_calls,s.num_base_calls)
这里答案会输出:
left: before superright: before superCalling method on Base ClassCalling method on Right SubclassCalling method on Left SubclassCalling method on Subclass(1, 1, 1, 1)
很明显,Base是只被执行了一次。但我们看调用顺序,它是先调用了LeftSubclass的call_me,然后它里面的super却指向了RightSubclass。其实,新式类里的调用顺序可以用__mro__来查看:
print Subclass.__mro__(<class '__main__.Subclass'>, <class '__main__.LeftSubclass'>, <class '__main__.RightSubclass'>, <class '__main__.BaseClass'>, <type 'object'>)
可以看到,类的调用顺序是Subclass -> Left -> Right -> Base,类似“广搜”,一旦找到后就马上返回。
0 0
- 3 When Objects are Alike
- When Are WDM Device Objects Created?
- when you are old
- When You Are Old
- When You Are Old
- When You Are Old
- When are Constructors Called?
- when you are young
- When you are old
- when you are old
- Are Repositories Domain Model Objects?
- When Are You Coming Home
- Poem: When You are Old
- Item7 Distinguish between () and {} when creating objects
- What are the objects in oracle?
- In Life We Are Happiest When…
- When parameters are available in post request.
- GNU make---When Variables Are Expanded
- ubuntu的一些必要设置
- POJ1287_最小生成树-Networking
- Java程序员们最常犯的10个错误
- 框架Spring的jar包下载
- C\C++语言中的计时函数
- 3 When Objects are Alike
- 北大ACM试题分类
- 《程序员面试宝典》学习记录2
- Ubuntu下安装jdk6的方法和步骤
- linux--cp指令
- 微信公众平台开发进阶篇资源集锦
- 合 JSONP 和 jQuery 快速构建强大的 mashup
- WebBrowser控件的使用
- IP地址,子网掩码、默认网关,DNS服务器是什么意思