Python类 基础知识
'''圆形类demo 类属性、实例属性、私有属性/方法 实例/类/静态方法 property装饰器'''
year = 2020 # 全局变量
class Circle(object):
pi = 3.14 # 类属性
__space = 'Euclid' #双_开头,类私有属性,无法在类外部访问
instance_num = 0 # 用来记录实例的数量
def __init__(self,r):
self.r = r # 实例属性的定义,self代表实例 实际上在任何时间/位置都可以使用该方式定义实例属性
self.__name = 'circle' + str(r) # 和类私有属性同理,不能在外部访问
Circle.instance_num += 1
def get_area(self):
# 实例方法,第一个参数为self
return self.r**2*Circle.pi # 这里可以使用Circle.pi or self.pi,但是直接r pi 是不可以的
def get_space(self):
return Circle.__space
def __get_name(self):
# 私有实例方法,只能在类内访问
return self.__name
def get_circle_name(self):
return self.__get_name()
@classmethod
def get_instance_num(cls):
# 类方法在调用时可使用类名/实例名,传给cls用来访问类属性。 类方法中只能使用类属性
return cls.instance_num
@staticmethod
def check_year():
# 静态方法不需要引用类或者实例,一般用来设置环境变量,修改另一个类的变量等
# 不需要传递类或者实例,因此,既可以使用类也可以使用实例来调用静态方法。
return year == 2020
def print_year_info(self):
if self.check_year():
print('This year is 2020!')
else:
print('This year is not 2020!')
@property
def name(self):
# 把方法变成属性调用 调用时instance.name即可
# 不设置name.setter的话是只读属性
return self.__name
@name.setter
def name(self,s):
# setter方法可以写入__name私有属性
self.__name = s
c1 = Circle(2) # 创建实例
c2 = Circle(3)
print(c1.r, c2.r, c1.pi, Circle.pi) # 访问类属性和实例属性 2 3 3.14 3.14
c1.pi = 3.1415 # 会为实例c1创建实例属性pi,不会修改类属性,c1.pi访问的是实例属性(优先级高)
print(c1.pi, c2.pi, Circle.pi) # 3.1415 3.14 3.14
del c1.pi # 删除实例的某实例属性
print(c1.pi,c2.pi,Circle.pi) # 3.14 3.14 3.14
print('c1的面积为:',c1.get_area()) # 调用实例方法
print(c1.get_space()) # 通过实例方法访问私有属性
# print(Circle.__space) #会报错
print(Circle._Circle__space) # 不推荐使用
print(c1.get_circle_name())
# print(c1.__get_name()) 会报错
print(c1._Circle__get_name(), c1._Circle__name) # 不推荐
print(Circle.get_instance_num(),Circle(4).get_instance_num()) # 实例的数目 2 3
print(Circle.check_year(), c1.check_year()) # 类/实例均可调用静态方法
c2.print_year_info()
# 三者区别: 实例方法和实例绑定(bound),类方法与类绑定,静态方法不与实例/类绑定。
# c1.get_area() 绑定的意思即c1.则把实例c1传入到了方法中,不需要写参数
print(c1.name) # property将方法作为属性调用 circle2
c1.name = 'new name' # 使用setter装饰器写入私有属性
print(c1.name) # new name
继承和派生
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
def call(self):
print(self.name + 'can call')
class Cat(Animal):
def __init__(self,name,age,sex):
super().__init__(name, age) # 这样才能继承来name age属性
self.sex = sex
def call(self):
print(self.name + 'can call "miao miao"')
class Tree(object):
def __init(self):
pass
def call(self):
print("I'm a tree")
def do_calling(obj):
obj.call()
animal = Animal('animal',5)
cat1 = Cat('cat1', 2, 'male')
print(cat1.name, cat1.age, cat1.sex)
cat1.call()
tree = Tree()
for i in [animal,cat1,tree]:
do_calling(i)
# 其他类不继承于 Animal,具备 call 方法也可以使用 do_calling 函数。这就是动态语言,动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。