类与对象
class Student(object):
pass
stu = Student
s = Student()
print (stu)
print (Student)
print (s)
结果是:
<class '__main__.Student'>
<class '__main__.Student'>
<__main__.Student object at 0x000002E28CE33E10>
## 0x000002E28CE33E10是内存地址
类的方法和字段
类的方法
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self
,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
类的属性
- 定义在类内部方法外部(类属性)
- 定义在方法内部(对象属性)
- 定义在 _ self _ 方法中
- 定义在其他方法中
- 对实例变量绑定任何数据
class Student(object):
sex = "man"
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
self.grade = 1
print('%s: %s' % (self.name, self.score))
print (Student.sex)
s = Student("zhangsan",95)
print (s.name)
print (s.sex)
#print (s.grade) -- 这个时候访问grade会出错
s.print_score()
print (s.grade)
s.count = "China"
print (s.count)
类的访问限制
私有变量
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
,在Python中,实例的变量名如果以 __
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
私有方法
方法前加两个下划线__
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def __print_score(self):
print('%s: %s' % (self.__name, self.__score))
s = Student("zhangsan",95)
s.__print_score()
# Traceback (most recent call last):
# File
# "C:/Users/disheng.zeng/Develop/Python/Scrapy/purePython1/main.py",
# line 27, in <module>
# s.__print_score()
# AttributeError: 'Student' object has no attribute '__print_score'
私有变量和特殊变量
在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private
变量,所以,不能用__name__
、__score__
这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name
,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量:
>>> bart._Student__name
'Bart Simpson'
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name
改成不同的变量名。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
继承和多态
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的。
class Animal(object):
def run(self):
print ("animal running...")
class Dog(Animal):
def run(self):
print ("dog running...")
class Car(object):
def run(self):
print ("car running...")
def showrun(animal):
animal.run()
showrun(Animal())
showrun(Dog())
showrun(Car())
静态语言 vs 动态语言
对于静态语言(例如Java
)来说,如果需要传入Animal
类型,则传入的对象必须是Animal
类型或者它的子类,否则,将无法调用run()
方法。
对于Python这样的动态语言来说,则不一定需要传入Animal
类型。我们只需要保证传入的对象有一个run()
方法就可以了:
- 本质上来讲是因为python在方法参数中不指定变量类型
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。